Boost logo

Boost Users :

From: Andreas Huber (ahd6974-spamgroupstrap_at_[hidden])
Date: 2006-02-21 17:21:49


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. 

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net