
Hi Dave, David Greene wrote:
David Greene wrote:
If I have an asynchronous state machine running in another thread and I send it an event, is there any way to have the sending thread block until the event is processed?
Yes: Add a boost::function member to the event. Have the member point to a function which calls notify_one() on a boost::condition. Have the sending thread call wait() on the condition. When processing the event inside the state_machine, call the boost::function member.
I need to use an asynchoronous machine
because the rest of my app is threaded but yet there are points where I must synchronize to know the machine is in a certain state before moving on.
From the documentation it seems like passing zero to FifoWorker::operator() (via fifo_scheduler::operator()) will do the trick, but I'm not sure.
See below.
Quick follow-up: when the documentation says that FifoWorker::operator() "must only be called from exactly one thread," does that mean it must be called only from one thread at any given time (i.e. it must be protected with mutexes or other concurrency protection) or that literally only one thread may ever call it and it must always be the same thread that calls it?
The latter. fifo_worker::operator() calls terminated(), which in turn returns the bool member terminated_. This call chain is not protected by mutexes. Picture the following scenario with one fifo_worker object: 1. Thread A, which is executed on CPU 1, calls operator(). Inside operator(), terminated_ is modified and operator() returns. 2. Thread B, which is executed on CPU 2, calls operator(), after thread A has returned from operator(). Nowadays both CPUs tend to have caches. Whether or not the cache contents is guaranteed to be written back to the main memory when thread A returns depends on the architecture of your hardware. IIRC, on X86 architectures there is such a guarantee. On other architectures you might need to use mutexes or a similar concept to guarantee that thread B sees the updates of thread A.
If it's the latter then that changes things quite dramatically and I probably want a blocking scheduler and will need to create another thread just to wait on empty and call operator() when full.
I'm not sure I understand that. You only need to create a blocking scheduler and call operator() on it, that's it. operator() will return when you call terminate() from any other thread. HTH & Regards, -- Andreas Huber When replying by private email, please remove the words spam and trap from the address shown in the header.