> Has anyone seen a segfault like this before? It's intermittent so that
> tells me there's some kind of race condition. Any idea how I can work
> around it?
Could it be a dangling event handler that is being called? Do you use
shared_ptr/shared_from_this?
Cheers,
Rutger
_______________________________________________
Boost-users mailing list
Boost...@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users
> Not using a shared_ptr_from_this, but I am using shared_ptr wrapped
> objects as parameters to my asynchronous callbacks...
>
If you use patterns like
boost::bind( &some_class::some_mem_fn, this, .... )
then it could be that the instance of some_class is destructed before the
bind-expression is. If the handler is called with "operation cancelled"
(which should happen with all waiting handlers if you call
io_service.stop()), it tries to make a call into freed memory -- you can
expect a crash, indeed. To solve this, one can use shared_from_this(),
boost::bind( &some_class::some_mem_fn, shared_from_this(), .... )
to make sure the object's lifetime will be at least that of the incomplete
handler.
> The only functions I'm binding with boost::bind are members of
> ClassifierContext, eg:
>
> ICMessage::async_read(socket_,
>
boost::bind(&ClassifierContext::handleCmdMsg,
> this,
> _1,_2,_3));
>
> Since the io_service object is stopped in the destructor of
> ClassifierContext, shouldn't that be OK? Or should
> I still try to create a shared_from_this off of the ClassifierContext
> class?
>
Not sure, given you are running multiple threads. According to the
documentation, io_service::stop() doesn't block, so it could still be
needing the shared_from_this stuff.
Another approach is to allocate the work object in your member io_loop of
ClassifierContext, and in the destructor, do something like
m_work_ptr.reset();
ioService_.run();
this makes sure all outstanding operations are finished.
Sean McAllister wrote:Not sure, given you are running multiple threads. According to the
> The only functions I'm binding with boost::bind are members of
> ClassifierContext, eg:
>
> ICMessage::async_read(socket_,
>
boost::bind(&ClassifierContext::handleCmdMsg,
> this,
> _1,_2,_3));
>
> Since the io_service object is stopped in the destructor of
> ClassifierContext, shouldn't that be OK? Or should
> I still try to create a shared_from_this off of the ClassifierContext
> class?
>
documentation, io_service::stop() doesn't block, so it could still be
needing the shared_from_this stuff.
Another approach is to allocate the work object in your member io_loop of
ClassifierContext, and in the destructor, do something like
m_work_ptr.reset();
ioService_.run();
this makes sure all outstanding operations are finished.
Cheers,
Rutger
That's right -- but you still would like to have all operations finished
before the end of the destructor. If you need to close sockets, call, e.g.,
socket::close.
Cheers,
Rutger
Sean McAllister wrote:That's right -- but you still would like to have all operations finished
>
> Hmmm, I've only got the one extra thread to run the asynchronous event
> loop
> in. If I have
> async_read events outstanding, wouldn't the above code cause my destructor
> to block
> until I've read another message (which may happen quite infrequently)?
>
before the end of the destructor. If you need to close sockets, call, e.g.,
socket::close.
Cheers,
Rutger