From: Anthony Williams (anthony_at_[hidden])
Date: 2006-03-10 07:06:23
I have now reimplemented condition variables for win32. After careful thought,
I decided that my previous implementation was subject to possible race
conditions, so I started again from scratch.
The new implementation of condition variables has templated wait functions, so
any type of lock can be used when waiting.
The basic idea is really simple. When a thread waits on the condition
variable, it is added to the back of the list of waiters. When a thread calls
notify_one, it wakes the head of the list; if a thread calls notify_all, it
wakes all list members.
The wakeup is implemented by using QueueUserAPC to queue an empty function on
the thread to be woken. The waiting threads wait using SleepEx to sleep in an
alertable state, and will be put in a ready state once Windows has queued the
APC. The thread will then resume when it is next scheduled. SleepEx will also
return if an async IO function completes, or any other APC is queued, so the
waiting thread must check the notified flag, and resume waiting if it has not
Internally, a boost::mutex is used to ensure that adding/removing from the
waiter list is atomic.
notify_all() first moves the whole list, so new threads can wait, but they
won't be notified by this call.
-- Anthony Williams Software Developer Just Software Solutions Ltd http://www.justsoftwaresolutions.co.uk