Boost logo

Boost Users :

Subject: [Boost-users] asio: async ops in multithreading environment
From: Max Dmitrichenko (dmitrmax_at_[hidden])
Date: 2013-03-05 08:43:57


Hi!

I have strange crashes of my application that uses async ops in
multiple threads. Before I describe my vision of the problem I point
the following:
1) I'm aware that shared access to the same socket from multiple
threads is unsafe.
2) All operations which my code issues on the same socket are made under mutex.

As far as I understand, the following happens:

1) One thread issues scatter-gather boost::asio::async_write() for
boost::array<boost::asio::const_buffer, 2> on socket A.
2) Another thread closes socket A after that.
3) Meantime (simultaneously with 2), first buffer write is completed
and one of the threads running io_service::run() starts to execute
second part of async_write from 1).

In this place application segfaults:

#0 0x00007fa3a3a2c4eb in boost::asio::detail::epoll_reactor::start_op
(this=0x19c3410, op_type=1, descriptor=27,
descriptor_data=@0x7f9dfc013260, op=0x7f9dfc2d2130,
allow_speculative=true)
    at boost-1_51/boost/asio/detail/impl/epoll_reactor.ipp:219
#1 0x00007fa3a3a2bf63 in
boost::asio::detail::reactive_socket_service_base::start_op
(this=0x19c4338, impl=..., op_type=1, op=0x7f9dfc2d2130,
is_non_blocking=true, noop=false)
    at boost-1_51/boost/asio/detail/impl/reactive_socket_service_base.ipp:211
#2 0x00007fa3a3af4ec5 in
boost::asio::detail::reactive_socket_service_base::async_send
(this=0x19c4338, impl=..., buffers=..., flags=0, handler=...)
    at boost-1_51/boost/asio/detail/reactive_socket_service_base.hpp:212
#3 0x00007fa3a3af90bf in
boost::asio::stream_socket_service<boost::asio::ip::tcp>::async_send
(this=0x19c4310, impl=..., buffers=..., flags=0, handler=...)
    at boost-1_51/boost/asio/stream_socket_service.hpp:298
#4 0x00007fa3a3b05992 in
boost::asio::basic_stream_socket<boost::asio::ip::tcp,
boost::asio::stream_socket_service<boost::asio::ip::tcp>
>::async_write_some (this=0x7f9dfc013250, buffers=..., handler=...)
    at boost-1_51/boost/asio/basic_stream_socket.hpp:676

because descriptor_data equals null-pointer here.

The problem is: second write which is issued internally by boost
cannot be protected by the same mutex which is used for protected
access to the socket in my code.

So, the question is: how can I safely close the socket?

--
Max

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net