Opened 8 years ago
#10624 new Bugs
win_object_handle_service race condition on destroy
Reported by: | Owned by: | chris_kohlhoff | |
---|---|---|---|
Milestone: | To Be Determined | Component: | asio |
Version: | Boost 1.54.0 | Severity: | Problem |
Keywords: | Cc: |
Description
I caught a random crash in our code base that appears to be due to a race condition in win_object_handle_service. Reproduction steps are essentially just:
boost::asio::windows::object_handle* handle = new boost::asio::windows::object_handle(service, hEvent);
handle->async_wait(...);
SetEvent(hEvent);
delete handle;
The race condition occurs in win_object_handle_service::wait_callback. The last few lines of code in this method are:
lock.unlock();
impl->owner_->io_service_.post_deferred_completions(completed_ops);
The problem is that while the delete of the handle waits on the same lock as the wait_callback, the call into impl->owner_->io_service_ happens outside the scope of that lock. Hence there is a race condition that can trigger under multi-threaded/heavy load scenarios where the delete may execute before the call to >io_service_.post_deferred_completions happens
lock.unlock();
<----- delete executes here
impl->owner_->io_service_.post_deferred_completions(completed_ops);
This leaves impl->owner_ pointing at deleted/unintialized memory, and hence the post_deferred_completions call randomly crashes. I can repro this 100% of the time by just adding a Sleep to emulate load:
lock.unlock();
Sleep(1000);
impl->owner_->io_service_.post_deferred_completions(completed_ops);