Problem in words:
For my application, I have a class that reads from a serial port. It uses Windows primitives for COM port handling and had a thread for asynchronous reading. I'm trying to convert this away from Windows primitives using Boost libraries such as Boost.Asio and Boost.Thread.
In the Windows port, my IO thread had several MFC CEvent variables, each of which represented a message: Read requested, Write requested, Read completed, Write completed, IO Cancelled. These were waited on with WaitForMultipleObjects.
The problem I have is that Boost.Thread seems to have analogues for neither CEvent nor WaitForMultipleObjects. The closest I have come is by discarding these and replacing the events with a set of booleans, and then using a condition_variable, which has its notify_all() function called whenever a boolean changes.
However, boost::condition_variable differs in one critical way from CEvent: if a CEvent is signalled while it is not being waited on, then the next wait on it immediately succeeds. With boost::condition_variable, any notify function is ignored if it is not waiting.
This means that there is always a gap between checking for the flags and waiting for the condition_variable in which a notification can be lost. This causes the thread to hang.
Does anybody know of a solution to this problem?
Problem in code:
// Old IO Thread
CEvent msg_cancel;
CEvent msg_read_req;
CEvent msg_write_req;
CEvent msg_read_comp;
CEvent msg_write_comp;
CEvent events[] = {
msg_cancel,
msg_read_req,
msg_write_req,
msg_read_comp,
msg_write_comp
};
bool cancel = false;
while (!cancel)
{
switch(WaitForMultipleObjects(5, events, false, INFINITE))
{
case WAIT_OBJECT_0 :
// msg_cancel
cancel = true;
break;
...
}
}
How to emulate that in Boost.Thread?