I know that OpenSSL, boost asio SSL implementation is based on, doesn't allow concurrent SSL_read() and SSL_write() (i.e. SSL_read() and SSL_write() executed by different threads).
Is it safe to call boost asio async_read() and async_write() on SSL socket from the same thread?
Thanks
The requirement for boost::asio::ssl:::stream
is for thread safety; it does not place a requirement as to which thread may initiate operations:
Distinct objects: Safe.
Shared objects: Unsafe. The application must also ensure that all asynchronous operations are performed within the same implicit or explicit strand.
If the application only has one thread processing the io_service
, and async_read()
and async_write()
are initiated from within that thread, then it is safe, as the operation and completion handler(s) are running within an implicit strand.
On the other hand, if multiple threads are processing the io_service
, then an explicit strand
is necessary. The async_read()
and async_write()
operations need to be initiated from within a strand
, and the completion handlers need to be wrapped by the same strand
.
For more details on Boost.Asio's thread safety requirements, strands
, and composed operations, consider reading this answer.
It is safe to call async_read()
and async_write()
on SSL socket from the same thread, but in general case it is not enough to avoid concurrency issues with ssl::stream. The actual requirement is provided in ssl::stream
documentation:
Thread Safety (...) Shared objects: Unsafe. The application must also ensure that all asynchronous operations are performed within the same implicit or explicit strand.
Of course, the standard boost::asio requirement to ensure that:
async_read
handler gets
called, andasync_write
handler gets called.must also be met.
Note, that it is allowed to schedule a read operation while a write operation is underway and conversely. Simultaneous asynchronous read and write operations are possible in ssl::stream
thanks to handling OpenSSL's network needs asynchronously through BIO
mechanism. SSL_read()
and SSL_write()
manifest their needs to communicate by returning SSL_ERROR_WANT_READ
and SSL_ERROR_WANT_WRITE
error codes. These error codes are used by ssl::stream
implementation to schedule the network operations asynchronously. A read or write operation on ssl::stream
may need multiple both read and write operations on the underlying network socket and multiple calls to SSL_read()
/ SSL_write()
, which will be performed from asynchronous network operation completion handlers (particularly not from the original async_read
/async_write
call), this is why it is not enough to ensure that async_read
and async_write
are not called simultaneously, but a strand is needed.
It is safe. But simulateous 2 or more async_write
-s on same socket are unsafe and will segfault often(at least for SSL case).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With