c++ - Do I need to use a boost::strand in this server model? -
i've been coding server quite time now. calling io_service::run more 1 thread, not sure if ned utilize strand here. since never calling async_read more once. though possible phone call async_write more 1 time if other connections need send others. code have far
void session::recvpacket() { boost::asio::async_read(m_socket, boost::asio::buffer(m_recv_buffer, len), boost::bind(&session::onread, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } void session::onread(const boost::system::error_code &e, size_t packet_length, size_t bytes_transferred) { if (e || bytes_transferred != packet_length) { if (e == boost::asio::error::operation_aborted) return; stop(); return; } // , send packet recvpacket(); } void session::sendpacket(packet &p) { boost::mutex::scoped_lock lock(send_mut); dword len = p.lenght(); m_crypt->makeheader(p.getraw().get(), static_cast<word>(len - 4)); m_crypt->encrypt(p.getraw().get() + 4, len - 4); boost::asio::async_write(m_socket, boost::asio::buffer(p.getraw().get(), len), boost::bind(&session::onpacketsend, this, len, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred, p.getraw())); } i not sure wheter threadsafe or not. if send part not threadsafe since can send more 1 packet @ 1 time (which going happen) should utilize strand there?
gz
yes, need strand.
as noted in tcp::socket documentation, concurrent calls on same socket (i.e. shared object) not thread safe. however, safe have multiple asynchronous operations pending on object. thus, safe:
and safe:
thread_1 | thread_2 --------------------------------------+--------------------------------------- socket.async_receive(...); | | socket.async_write_some(...);but specified not beingness safe:
thread_1 | thread_2 --------------------------------------+--------------------------------------- socket.async_receive(...); | socket.async_write_some(...); |furthermore, send_mut mutex in session::sendpacket() provides no real safety m_socket. boost::asio::async_write() operation composed operation, made of 0 or more call's m_socket.async_write_some() function. due lifespan of lock , behavior of asynchronous operations, lock not guarantee mutex held during or of async_write_some() operations.
for more details on thread safety , strands, consider reading this answer.
also, aware 1 time async_write() operation has been initiated on stream, programme must ensure no other write occurs on stream until initial operation's completion handler has been invoked:
the programme must ensure stream performs no other write operations (such async_write, stream's async_write_some function, or other composed operations perform writes) until operation completes.
if multiple writes need performed, consider queuing writes, shown in this answer. type of solution may create managing lifespan of packet object's underlying buffer easier, queue own re-create of data, meeting async_write() operation's requirement buffer's underlying memory blocks remain valid until completion handler called.
c++ boost-asio
No comments:
Post a Comment