Concurrent Event Handlers have race conditions. How to fix fix them? - concurrency

Event handler E1 makes a long running network request.
Event handler E2 is very quick and doesn't make a network request. It writes to database.
E1 is guaranteed to start to execute before E2 however, E1 finishes after E2. How can I force that E2 always finishes after E1?
Thanks.

You didn't mention any language. I like Java, but you can find something like Semaphore in many languages and libraries.
Semaphore sem = new Semaphore(0);
void E1(...) {
doSomeStuff();
sem.release();
}
void E2(...) {
doStuffThatsSafeToDoWhile_E1_StillIsDoingItsStuff();
sem.acquire();
doStuffThatMustWaitUntilAfter_E1_IsFinished();
}
This will work for just one pair of calls to E1 and E2. I don't want to suggest any way to "reset" it to be used again and again. I'll leave that part up to you because I don't want to assume anything about the relationship between E1 and E2. I don't know why there is stuff that must wait until E1 is finished. I don't know what "finished" really means. If E1 and E2 are allowed to be called again, I don't know what had to happen in order to allow it.
Edit:
Maybe, at a high level, you're really only handling one "event," but at a low-level, you get the notification of that event in two parts.
If so, then how about we do all of the work to handle the high-level event within one handler function, and let the other handler function do nothing except open a gate when it's safe for the first one to finish whatever needs to be finished?
Semaphore sem = new Semaphore(0);
void E1(...) {
doStuffThatCanBeSafelyDoneBefore_E2_isCalled();
sem.acquire();
doStuffThatMustNotBeDoneUntilAfter_E2_isCalled();
}
void E2(...) {
sem.release();
}

Related

What is the best way to compose a state machine using Boost SML to manage ASIO objects and threads?

First of all, I'd like to clarify that by ASIO objects I mean a simple timer for the time being, but further down the line I want to create a state machine to deal with sockets and data transmission.
I have been exploring the Boost SML library for about a few weeks now and trying out different things. I quite like it, however the documentation doesn't help in my use case and its source is not exactly inviting for someone still fairly new to metaprogramming.
For the time being, I'd like to create a state machine that manages an ASIO timer (to wait asynchronously). The interface would provide a start call where you can tell it how long it should wait, a cancel call (to cancel an ongoing wait), and some callback to be invoked when the timer fires.
I have already achieved this in one way, following both sml examples in this repository and it works well - I have a class which manages the timer and contains a state machine. The public interface provides means to inject the appropriate events into the FSM and query its state. The private interface provides means to start and stop the timer. The FSM class is a friend to the controller so it has access to the private functions.
However I was wondering if there is a way to take some of the controller functionality and move it into the FSM - it would hold all ASIO objects and run the io_context/io_service in a thread it has spawned.
(1) First problem I'd encounter is the fact that the state machine is copied - ASIO objects don't allow this, but this can be worked around by wrapping them in shared pointers.
(2) Next is, sending events to the FSM from within. I figured out how to do it from actions by obtaining a callable boost::sml::back::process<> object and using this to "post" the event to the queue, but this would be useless from an ASIO handler as this by default would not be invoked from an action. I suppose a way around this is to capture the callable into the timer handler with a lambda, like this:
// Some pseudo code (this would all be done in one class):
// Transition table
"idle"_s + event<Wait> / start_waiting = "waiting"_s
// Events
struct Wait { std::chrono::seconds duration; };
struct Cancel {};
struct Expire {};
// Actions
std::function<void(Wait const&, boost::sml::back::process<Cancel, Expire>)> start_waiting =
[this] (Wait const& e, boost::sml::back::process<Cancel, Expire> p) {
run_timer(e, p);
};
// Private function
void run_timer(Wait const& e, boost::sml::back::process<Cancel, Expire>& p) {
m_timer->expires_after(e.duration);
auto timerHandler = [&p] (asio::error_code const& e) {
if (e == asio::error::operation_aborted)
p(Cancel{});
else
p(Expire{});
};
timer->async_wait(timerHandler);
}
But this feels like a bit of a botch.
(3) The last thing that worries me is how the state machine will handle threads. Obviously the timer handler will be executed in its own thread. If that posts an event to the queue of the FSM, will that event be processed by the same thread that posted it? I'm assuming yes, because I can't see any mentions of threads (other than thread safety) in the header. This will dictate how I go about managing the threads' lifetime.
Any tips on alternative ways to architect this, and their pros and cons, would be of great help.

How to use volatile multimap iterator?

I need to use a volatile multimap iterator, but iterator's operators (such as ++) doesn't work when it is defined as volatile...
First of all: why do I need a volatile iterator (and NOT a mutable one)?
I write an utility class (Echeancier) which must schedule a list of deadlines (Echeance), ordered by date.
All the deadlines are stored in a multimap whose key is the deadline's date (_echeancesParDate).
Each deadline is managed successively, with only one linux timer:
- when timer expires, it generates a signal;
- signal's handler handles the event associated to the deadline and then, shall restart the timer for the next deadline.
So I need to use typeListeEcheancesParDate::iterator _comingEcheance in a signal handler.
On the other hand, class Echeancier also defines a function to create new deadlines (ajouterEcheance()).
This function may update _comingEcheance.
That's why I need to define _comingEcheance as volatile.
NB: for the moment, I put the atomic access aspect aside.
My source code (partial):
class Echeancier
{
private:
typedef std::multimap<Echeance::typeDateEcheance, Echeance*> typeListeEcheancesParDate;
typeListeEcheancesParDate _echeancesParDate;
typeListeEcheancesParDate::iterator volatile _comingEcheance;
void handlerEcheance(Echeance::typeEvenementEcheance eventEcheance);
AsyncTimer<Echeancier>* _timer;
int _numSignalTimer;
protected:
Echeancier(int signalEcheance);
~Echeancier();
virtual void traiterEvenement(Echeance::typeEvenementEcheance eventEcheance) = 0;
int ajouterEcheance(Echeance::typeDateEcheance date,
Echeance::typeEvenementEcheance evenement,
Echeance::typeIdentifiantEcheance & idEcheance);
int supprimerEcheance(Echeance::typeIdentifiantEcheance idEcheance);
}
The only idea I have is to overload multimap iterator ++ operator, to make it works with volatile modifier...
But I don't know how to do this... any idea for my problem?
Thanks
So, I made a comment saying that volatile is a bad smell in multithreaded contexts, and I stand by that.
It is also a bad smell to manipulate your data in a signal handler. Using locks also don't work in signal handlers, since there is no other thread to unlock a lock held by the main thread of the program.
I'd argue that you need to rethink your whole design, and use two threads [one of which may be controlled by a timer signal handler, and have a high priority]. The point is that manipulating your iterator and the data the iterator points at, will have to be dealt with atomically, and just marking something volatile does not solve that - volatile just means that the compiler has to "do exactly what the code says to do" - but it doesn't mean that your data itself is safe.

Event based state machine in c++ with coroutines

Co-routines in c++ is a really powerful technique for implementing state machines however examples that I find on the internet are overly simplistic, e.g. they usually represent some kind of iterator which after calling to some "Next" routine moves along, dependent only on initial arguments of the coroutine. However in reasonably complicated event based state machines each next step depends, on the specific event received which caused to resume the running and also some default event handlers should be implemented for events that can occur at any time.
Suppose we have a simple phone state machine.
STATE:HOOK OFF-->[EVT:DIAL TONE]--> [STATE:DIALING] --> [EVT: NUMBER DIALED] --> STATE:TALKING.
Now I would like a coroutine that would see something like.
PhoneSM()
{
HookOf();
Yield_Till(DialTone_Event);
Dial();
Yield_Till(EndOfDial_Event);
Talk();
...
}
e.g. requirements
Yield_Till would only continue when specific event was receive (how???) when the couroutine run is resumed.If not then it should yield again.
Yield_Till must know how to run the events to default handlers like Hangup_Event because really it can happen any time and it will be cumbersome to add it yield call each time.
Any help with c++ (only!!!) implementation or ready made infrastructures for meeting the requirements will be highly appreciated.
It seems to me that you are trying to code an event-driven state machine as a sequential flow-chart. The difference between state-charts and flow-charts is quite fundamental, and is explained, for example in the article "A Crash Course in UML State Machines":
A state machine should be rather coded as a one-shot function that processes the current event and returns without yielding or blocking. If you wish to use co-routines, you can call this state-machine function from a co-routine, which then yields after each event.
This is an old question but the first I found when searching how to achieve this with C++20 coroutines. As I already implemented it a few times with different approaches I still try to answer it for future readers.
First some background why this is actually a state machine. You might skip this part if you are only interested in how to implement it. State machines were introduced as a standard way to do code that is called once in a while with new events and progresses some internal state. As in this case program counter and state-variables obviously can't live in registers and on stack there is some additional code required to continue where you left of. State machines are a standard way to achieve this without extreme overhead. However it is possible to write coroutines for the same task and every state-machine could be transferred in such a coroutine where each state is a label and the event handling code ends with a goto to the next state at which point it yields. As every developer knows goto-code is spaghetti code and there is a cleaner way to express the intent with flow-control structures. And in fact I have yet to see a state-machine which couldn't be written in a more compact and easier to understand way using coroutines and flow-control. That being said: How can this be implemented in C/C++?
There are a few approaches to do coroutines: it could be done with a switch statement inside a loop like in Duff's device, there were POSIX coroutines which are now obsolete and removed from the standard and C++20 brings modern C++ based coroutines. In order to have a full event-handling state-machine there are a few additional requirements. First of all the coroutine has to yield a set of events that will continue it. Then there needs to be a way to pass the actually occurred event together with its arguments back into the coroutine. And finally there has to be some driver code which manages the events and registers event-handlers, callbacks or signal-slot connections on the awaited events and calls the coroutine once such an event occurred.
In my latest implementations I used event objects that reside inside the coroutine and are yielded by reference/pointer. This way the coroutine is able to decide when such an event is of interest to it even when it might not be in a state where it is able to process it (e.g. a response to a previously send request got answered but the answer isn't to be processed yet). It also allows to use different event-types that might need different approaches to listen for events independent from the used driver code (which could be simplified this way).
Here is a small Duff's device coroutine for the state-machine in the question (with an extra occupied event for demonstration purpose):
class PhoneSM
{
enum State { Start, WaitForDialTone, WaitForEndOfDial, … };
State state = Start;
std::unique_ptr<DialTone_Event> dialToneEvent;
std::unique_ptr<EndOfDial_Event> endOfDialEvent;
std::unique_ptr<Occupied_Event> occupiedEvent;
public:
std::vector<Event*> operator()(Event *lastEvent = nullptr)
{
while (1) {
switch (state) {
case Start:
HookOf();
dialToneEvent = std::make_unique<DialTone_Event>();
state = WaitForDialTone;
// yield ( dialToneEvent )
return std::vector<Event*>{ dialToneEvent.get() };
case WaitForDialTone:
assert(lastEvent == dialToneEvent);
dialToneEvent.reset();
Dial();
endOfDialEvent = std::make_unique<EndOfDial_Event>();
occupiedEvent = std::make_unique<Occupied_Event>();
state = WaitForEndOfDial;
// yield ( endOfDialEvent, occupiedEvent )
return std::vector<Event*>{ endOfDialEvent.get(), occupiedEvent.get() };
case WaitForEndOfDial:
if (lastEvent == occupiedEvent) {
// Just return from the coroutine
return std::vector<Event*>();
}
assert(lastEvent == endOfDialEvent);
occupiedEvent.reset();
endOfDialEvent.reset();
Talk();
…
}
}
}
}
Of course implementing all the coroutine handling makes this overly complicated. A real coroutine would be much simpler. The following is pseudocode:
coroutine std::vector<Event*> PhoneSM() {
HookUp();
{
DialToneEvent dialTone;
yield { & dialTone };
}
Dial();
{
EndOfDialEvent endOfDial;
OccupiedEvent occupied;
Event *occurred = yield { & endOfDial, & occupied };
if (occurred == & occupied) {
return;
}
}
Talk();
…
}
Most co-routine libraries do not off sophisticated yield function. They simply yield and your co-routine will get control back at some arbitrary point. Hence, after a yield you will have to test the appropriate conditions in your code and yield again if they are not met. In this code you would also put tests for events like hangup, in which case you would terminate your co-routine.
There are a number of implementation in the public domain and some operating systems (e.g. Windows) offer co-routine services. Just google for co-routine or fiber.

Boost MSM - clearer

I want to use boost msm state machine but i am having a hard time imagining how it works. Let say we only have 2 states (s1, s2) and to go from s1 to s2 you need event e1 to be fired and to bo back you need another one e2.
e1 and e2 can only be fired from within s1 and s2 respectively.
Now in main() I start by starting the statemachine (start()) then ill have a while loop that every 1 min will go back to the state machine but have to pick up from where it left.i.e.
main()
{
MSM.start(); //start state machine
while (a_condition)
{
ProcessInputsfromIO();
Go_backtoStatemachine(); //how can i do this?
delay(1min)
}
MSM.stop();
}
So basically when a state finishes executing, the statemachine will exit, then ill have a delay of 1 minutes, then the while loop will need to take me back to the state I was before I exit, or I think that's how we should implement a state machine.
Is what I am asking for out of the ordinary? If yes then how do people implement a non-blocking state machine? if no, then how can I implement Go_backtoStatemachine()?
There is a fairly simple example here:
MSM Simple Tutorial
A state machine is an abstract concept. It has states, events, etc. It does not really have a concept of blocking, non blocking, etc. Within the framework of Boost MSM you can call start() to enter the initial state, process_event() to inject events, and stop() to stop. The state machine simply captures system state and can call some functions as the system changes state. How you would use it is very application dependant.
MSM has not any knowledge of threads, so when start() or process_event(MyEvent()) are called, they are executed on the current thread. It's possible to defer the event processing to a later moment though (which is still NOT thread-safe), as explained on the docs (https://www.boost.org/doc/libs/1_75_0/libs/msm/doc/HTML/ch03s05.html#d0e2668):
Enqueueing events for later processing
Calling process_event(Event const&) will immediately process the event
with run-to-completion semantics. You can also enqueue the events and
delay their processing by calling enqueue_event(Event const&) instead.
Calling execute_queued_events() will then process all enqueued events
(in FIFO order). Calling execute_single_queued_event() will execute
the oldest enqueued event.
You can query the queue size by calling get_message_queue_size().
In the question's example then, you can
enqueue the events inside ProcessInputsfromIO as
void ProcessInputsfromIO(){
somethingToDo();
myfsm.enqueue_event(myEvent1());
somethingElseToDo();
etc();
}
Go_backtoStatemachine() becomes simply myfsm.execute_queued_events()

Elegant ways to notify consumer when producer is done?

I'm implementing a concurrent_blocking_queue with minimal functions:
//a thin wrapper over std::queue
template<typename T>
class concurrent_blocking_queue
{
std::queue<T> m_internal_queue;
//...
public:
void add(T const & item);
T& remove();
bool empty();
};
I intend to use this for producer-consumer problem (I guess, it is where one uses such data structures?). But I'm stuck on one problem which is:
How to elegantly notify consumer when producer is done? How would the producer notify the queue when it is done? By calling a specifiic member function, say done()? Is throwing exception from the queue (i.e from remove function) a good idea?
I came across many examples, but all has infinite loop as if the producer will produce items forever. None discussed the issue of stopping condition, not even the wiki article.
I've simply introduced a dummy "done" product in the past. So if the producer can create "products" of, say, type A and type B, I've invented type "done". When a consumer encounters a product of type "done" it knows that further processing isn't required anymore.
It is true that it's common to enqueue a special "we're done" message; however I think OP's original desire for an out-of-band indicator is reasonable. Look at the complexity people are contemplating to set up an in-band completion message! Proxy types, templating; good grief. I'd say a done() method is simpler and easier, and it makes the common case (we're not done yet) faster and cleaner.
I would agree with kids_fox that a try_remove that returns an error code if the queue is done is preferred, but that's stylistic and YMMV.
Edit:
Bonus points for implementing a queue that keeps track of how many producers are remaining in a multiple-producers situation and raises the done exception iff all producers have thrown in the towel ;-) Not going to do that with in-band messages!
My queues have usually used pointers (with an std::auto_ptr in the
interface, to clearly indicate that the sender may no longer access the
pointer); for the most part, the queued objects were polymorphic, so
dynamic allocation and reference semantics were required anyway.
Otherwise, it shouldn't be too difficult to add an “end of
file” flag to the queue. You'd need a special function on the
producer side (close?) to set it (using exactly the same locking
primitives as when you write to the queue), and the loop in the removal
function must wait for either something to be there, or the queue to be
closed. Of course, you'll need to return a Fallible value, so that
the reader can know whether the read succeeded or not. Also, don't
forget that in this case, you need a notify_all to ensure that all
processes waiting on the condition are awoken.
BTW: I don't quite see how your interface is implementable. What does
the T& returned by remove refer to. Basically, remove has to be
something like:
Fallible<T>
MessageQueue<T>::receive()
{
ScopedLock l( myMutex );
while ( myQueue.empty() && ! myIsDone )
myCondition.wait( myMutex );
Fallible<T> results;
if ( !myQueue.empty() ) {
results.validate( myQueue.top() );
myQueue.pop();
}
return results;
}
Even without the myIsDone condition, you have to read the value into a
local variable before removing it from the queue, and you can't return a
reference to a local variable.
For the rest:
void
MessageQueue<T>::send( T const& newValue )
{
ScopedLock l( myMutex );
myQueue.push( newValue );
myCondition.notify_all();
}
void
MessageQueue<T>::close()
{
ScopedLock l( myMutex );
myIsDone = true;
myCondition.notify_all();
}
'Stopping' is not often discussed because it's often never done. In those cases where it is required, it's often just as easier and more flexible to enqueue a poison-pill using the higher-level P-C protocol itself as it is to build extra functionality into the queue itself.
If you really want to do this, you could indeed set a flag that causes every consumer to raise an exception, either 'immediately' or whenever it gets back to the queue, but there are problems. Do you need the 'done' method to be synchronous, ie. do you want all the consumers gone by the time 'done' returns, or asynchronous, ie. the last consumer thread calls an event parameter when all the other the consumers are gone?
How are you going to arrange for those consumers that are currently waiting to wake up? How many are waiting and how many are busy, but will return to the queue when they have done their work? What if one or more consumers are stuck on a blocking call, (perhaps they can be unblocked, but that requires a call from another thread - how are you going to do that)?
How are the consumers going to notify that they have handled their exception and are about to die? Is 'about to die' enough, or do you need to wait on the thread handle? If you have to wait on the thread handle, what is going to do the waiting - the thread requesting the queue shutdown or the last consumer thread to notify?
Oh yes - to be safe, you should arrange for producer threads that turn up with objects to queue up while in 'shutting down' state to raise an exception as well.
I raise these questions becasue I've done all this once, a long time ago. Eventually, it all worked-ish. The objects queued up all had to have a 'QueuedItem' inserted into their inheritance chain, (so that a job-cancellation method could be exposed to the queue), and the queue had to keep a thread-safe list of objects that had been popped-off by
threads but not processed yet.
After a while, I stopped using the class in favour of a simple P-C queue with no special shutdown mechanism.