Boost::Threads condition variable on Win32 and IO completion routines
The start of the do_wait() method of a boost::condition (in 1.29.0) for Win32 looks like this void condition::do_wait() { int res = 0; res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_queue), INFINITE); assert(res == WAIT_OBJECT_0); This waits indefinitely until m_queue is signalled. Would it be safe to change this so the thread is alertable for IO completion routines? Something like int res = 0; while ((res = WaitForSingleObjectEx(reinterpret_cast<HANDLE>(m_queue), INFINITE, true)) == WAIT_IO_COMPLETION) { } assert (res == WAIT_OBJECT_0); We make fairly heavy use of Waitable Timers in our statemachines. The completion routine for a timer is called back in the context of the thread that started it, when the thread is alertable. WaitForSingleObject doesn't allow the thread to be alertable. We currently use this in our own thread (with Windows events) but are looking to update the message queue code and thread code to use boost. With out this change, it would currently break a lot of code if we were to use condition variables. Thanks Russell
Russell Hind said:
The start of the do_wait() method of a boost::condition (in 1.29.0) for Win32 looks like this
void condition::do_wait() { int res = 0; res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_queue), INFINITE); assert(res == WAIT_OBJECT_0);
This waits indefinitely until m_queue is signalled. Would it be safe to change this so the thread is alertable for IO completion routines? Something like
int res = 0; while ((res = WaitForSingleObjectEx(reinterpret_cast<HANDLE>(m_queue), INFINITE, true)) == WAIT_IO_COMPLETION) { } assert (res == WAIT_OBJECT_0);
We make fairly heavy use of Waitable Timers in our statemachines. The completion routine for a timer is called back in the context of the thread that started it, when the thread is alertable. WaitForSingleObject doesn't allow the thread to be alertable.
I've not made use of alertable threads in Win32 to date. Is it generally a good idea to make all waits alertable, or should this be something that the user can specify (which will be fun to make portable, but that's my problem)? Wouldn't you want all waits to be alertable, and not just this specific one in boost::condition?
We currently use this in our own thread (with Windows events) but are looking to update the message queue code and thread code to use boost. With out this change, it would currently break a lot of code if we were to use condition variables.
This doesn't work for Windows messages, does it? For that you need MsgWaitForObject(Ex), right? That's one that's more difficult to address for a number of reasons, but it should be addressed as well, and is on my list of todos. -- William E. Kempf
William E. Kempf wrote:
I've not made use of alertable threads in Win32 to date. Is it generally a good idea to make all waits alertable, or should this be something that the user can specify (which will be fun to make portable, but that's my problem)? Wouldn't you want all waits to be alertable, and not just this specific one in boost::condition?
I think that has to be considedered carefully before making the change. Especially reentrancy issues could be tricky if we wait in an alertable state. And I don't know about fairness issues, but my guess would be that a thread with lots of apcs and iocps posted on the thread would be starved. Maybe a special build of boost.threads with a warning label ;). But maybe you will have to enter an alertable state to be able to implement cancellations (by queuing an apc to be waited for on specific cancellation points which in this case would be all the cases when the user does an alertable wait).
We currently use this in our own thread (with Windows events) but are looking to update the message queue code and thread code to use boost. With out this change, it would currently break a lot of code if we were to use condition variables.
This doesn't work for Windows messages, does it? For that you need MsgWaitForObject(Ex), right? That's one that's more difficult to address for a number of reasons, but it should be addressed as well, and is on my list of todos.
Alertable waits can be entered by WaitForMultipleObjectsEx, WaitForSingleObjectEx, MsgWaitForObjectEx, SleepEx, SignalObjectAndWait. But the reentrancy issues would also apply for MsgWaitForObject(Ex). Because I guess the purpose would be to enter a message loop if it signals that there is something in the event queue. I don't know how portable the concept would be. But maybe some kind of intteruptable wait concept would have to be introduced? But in the Windows case one would have to enter the interuptible wait state and determine the cause of interruption wich could be apc, iocp or a message in the message queue. But I think theres some nasty things lurking with these issues that shouldn't be taken lightly. /michel
participants (3)
-
Michel Andr�
-
Russell Hind
-
William E. Kempf