Removed some of the clumsy code.
I had a function that resolved an address and initiated async_connect; this function was called from the socket thread.
When I called it from the main thread instead, the crash disappeared.

It seems that async_connect should not be called from the same service or thread that the socket is working on.

I wonder if this is correct or I have made a mistake somewhere that causes such behavior.

Thanks!

2011/6/24 Indrek Sünter <indreksnt@gmail.com>
Hi,

Thanks for the response.

True, the source of the problem might be there. Commented socket creation out and it no longer crashed.
With only async_connect left in (only call, for which the socket is used), it still crashes.

Here is how I tried to circumvent this problem (and it probably still doesn't work):

On destruction, I lock the class mutex and mark the class as broken (a boolean flag).
All dispatched handlers start with a loop that checks if the class is broken and tries to lock the mutex. When the class is broken, the aforementioned socket shutdown code is called and the handler returns.
With the help of another mutex, class destructor waits for the socket shutdown code to finish (which is called from the same service, on which the socket handlers are run - to avoid racing conditions).
In every class function, the class state is checked for broken.

It's really clumsy and although it's supposed to be bulletproof (in theory), it still doesn't work. There must be a better way to do this.

Though, it seems strange that socket deinitialization went without problems, service was stopped, thread was joined and now service destruction fails.
There should no longer be nothing running on it, right?

Any suggestions?
Thanks!

On Fri, Jun 24, 2011 at 8:58 PM, Marat Abrarov <abrarov@mail.ru> wrote:
Hi, Indrek.

> // m_socket was associated with m_service
> m_socket->cancel();
> m_socket->shutdown( boost::asio::ip::tcp::socket::shutdown_both, ec );
> m_socket->close( ec );
> delete m_socket;
> m_socket = NULL;
>
> // Delete work on the service
> delete m_work;
> m_work = NULL;
>
> // Stop the service
> m_service->stop();
>
> // Join the thread this service was running on
> m_thread->interrupt();
> m_thread->join();
> delete m_thread;
> m_thread = NULL;
>
> // Crashes here
> delete m_service;
> m_service = NULL;
>
> Here's what VC10 reported:
> Access violation
> camc.exe!boost::asio::detail::socket_ops::send(unsigned int s, const _WSABUF
> * bufs, unsigned int count, int flags, boost::system::error_code & ec) Line
> 876 + 0x24 bytes C++
> camc.exe!boost::asio::detail::socket_select_interrupter::interrupt() Line
> 127 + 0x18 bytes C++
> camc.exe!boost::asio::detail::select_reactor::shutdown_service() Line 73 C++
> camc.exe!boost::asio::detail::service_registry::~service_registry() Line 42
> + 0xf bytes C++
> camc.exe!boost::asio::detail::service_registry::`scalar deleting
> destructor'() + 0x16 bytes C++
> camc.exe!boost::asio::io_service::~io_service() Line 51 + 0x1f bytes C++
> camc.exe!boost::asio::io_service::`scalar deleting destructor'() + 0x16
> bytes C++

May be the source of your problem is located in yours async write completion handler (it is often so - see asio-users
mailing list). It seems that your completion handler tries to use destroyed m_socket.

Regards,
Marat Abrarov.


_______________________________________________
Boost-users mailing list
Boost-users@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users