Skip to content
Snippets Groups Projects
Commit bdfc155c authored by Florian Fischer's avatar Florian Fischer
Browse files

prevent lost stop() calls

Currently the write to 'state' from stop() is overridden in actorLoop()
if it occurs while the Actor is executing the while loop body in actorLoop()
because the while loop body unconditionally writes 'state'.

To prevent those lost 'state' updates actorLoop() now uses compare_exchange
to switch 'state'.
parent 615f227f
No related branches found
No related tags found
1 merge request!9fix Actor and UnboundedBlockingMpscQueue
...@@ -23,6 +23,10 @@ private: ...@@ -23,6 +23,10 @@ private:
UnboundedBlockingMpscQueue<T> queue; UnboundedBlockingMpscQueue<T> queue;
bool switchState(State oldState, State newState) {
return state.compare_exchange_strong(oldState, newState, std::memory_order_acq_rel);
}
void setState(State newState) { void setState(State newState) {
state.store(newState, std::memory_order_release); state.store(newState, std::memory_order_release);
} }
...@@ -30,16 +34,19 @@ private: ...@@ -30,16 +34,19 @@ private:
void actorLoop() { void actorLoop() {
setState(Running); setState(Running);
while (state == Running) { while (state.load(std::memory_order_acquire) == Running) {
setState(Retrieving); if (!switchState(Running, Retrieving)) {
// Someone else must have set our state to Stopped
break;
}
T t = queue.get([this] { T t = queue.get([this] {
setState(Running); // Prevent lost stop()
switchState(Retrieving, Running);
}); });
receive(t); receive(t);
} }
setState(Stopped);
} }
protected: protected:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment