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.ippto sleep immediately afterdo_poll_oneruns 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_onereturning0if 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.