Opened 10 years ago
Closed 9 years ago
#8354 closed Bugs (fixed)
Only thread blocked in io_service.run() is not processing event loop.
Reported by: | Owned by: | chris_kohlhoff | |
---|---|---|---|
Milestone: | To Be Determined | Component: | asio |
Version: | Boost Development Trunk | Severity: | Problem |
Keywords: | Cc: | samjmill@…, davidjoelschwartz@… |
Description
There is a concurrency issue in task_io_service
(Boost 1.48+), that can leave a thread blocked in io_service.run()
, waiting for its wakeup_event
to be signaled. If thread A invokes io_service::poll()
, runs the reactor while thread B invokes io_service.run()
, becoming an idle thread (op_queue_
is empty), then if no work is ready to run, thread A io_service::poll()
returns 0
without waking up the idle thread B. This results in thread B remaining blocked on io_service::run()
, but never processing the event loop.
A side-by-side visualization illustrating the problem:
poll thread | main thread ---------------------------------------+--------------------------------------- lock() | do_poll_one() | |-- pop task_operation_ from | | queue_op_ | |-- unlock() | lock() |-- create task_cleanup | do_run_one() |-- service reactor (non-block) | `-- queue_op_ is empty |-- ~task_cleanup() | |-- set thread as idle | |-- lock() | `-- unlock() | `-- queue_op_.push( | | task_operation_) | `-- task_operation_ is | queue_op_.front() | `-- return 0 | // still waiting on wakeup_event unlock() |
Attached files are:
- Patch file that modifies
task_io_service.ipp
to sleep immediately afterdo_poll_one
runs the reactor. This is only used to increase the changes of reproducing the concurrency problem. - Test application:
- An asynchronous work loop via a timer that will print "." every 3 seconds.
- Spawn off a single thread that will poll the
io_service
. - Delay to allow the new thread time to poll
io_service
, and have main callio_service::run()}} while the poll thread sleeps in {{{task_io_service::do_poll_one()
.
- Patch with suggested fix that invokes
wake_one_thread_and_unlock()
beforedo_poll_one
returning0
if no work is to be done after running the reactor.
Attachments (3)
Change History (6)
by , 10 years ago
Attachment: | test.patch added |
---|
by , 10 years ago
Test application used with test.patch task_io_service.
comment:1 by , 10 years ago
Cc: | added |
---|
comment:2 by , 10 years ago
Cc: | added |
---|
comment:3 by , 9 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Patch task_io_service to increase changes of reproducing concurrency problem.