commit 0a5445867e602672beb45a2d1517abed414fbe25
parent 8484e6e4fdd6f1816506d17a7fad2f8fd5d927af
Author: Johannes Lorenz <j.git@lorenz-ho.me>
Date: Sun, 28 Jul 2019 21:48:36 +0200
Master::runOsc(): Fix possible race condition
Fix a race condition when MiddleWare has taken over a dead Master, and
Master just came alive again. In such a case, only one thread does stuff
in Master::runOsc(), the other skips it.
Diffstat:
2 files changed, 36 insertions(+), 18 deletions(-)
diff --git a/src/Misc/Master.cpp b/src/Misc/Master.cpp
@@ -1123,28 +1123,43 @@ int msg_id=0;
bool Master::runOSC(float *outl, float *outr, bool offline)
{
- //Handle user events
- char loc_buf[1024];
- DataObj d{loc_buf, 1024, this, bToU};
- memset(loc_buf, 0, sizeof(loc_buf));
-
- int events = 0;
- for(; uToB && uToB->hasNext() && events < 100; ++msg_id, ++events)
+ // the following block is only ever entered by 1 thread at a time
+ // other threads have to ignore it
+ if(!run_osc_in_use.exchange(true)) // exchange returns value before call
{
- const char *msg = uToB->read();
- if(! applyOscEvent(msg, outl, outr, offline, true, d, msg_id) )
- return false;
- }
+ /*
+ * WARNING: Do not return without "run_osc_in_use.store(false)"
+ */
- if(automate.damaged) {
- d.broadcast("/damage", "s", "/automate/");
- automate.damaged = 0;
- }
+ //Handle user events
+ char loc_buf[1024];
+ DataObj d{loc_buf, 1024, this, bToU};
+ memset(loc_buf, 0, sizeof(loc_buf));
- if(events>1 && false)
- fprintf(stderr, "backend: %d events per cycle\n",events);
+ int events = 0;
+ for(; uToB && uToB->hasNext() && events < 100; ++msg_id, ++events)
+ {
+ const char *msg = uToB->read();
+ if(! applyOscEvent(msg, outl, outr, offline, true, d, msg_id,
+ ) )
+ {
+ run_osc_in_use.store(false);
+ return false;
+ }
+ }
- return true;
+ if(automate.damaged) {
+ d.broadcast("/damage", "s", "/automate/");
+ automate.damaged = 0;
+ }
+
+ if(events>1 && false)
+ fprintf(stderr, "backend: %d events per cycle\n",events);
+
+ run_osc_in_use.store(false);
+ return true;
+ }
+ else { return true; /* = no new master */ }
}
/*
diff --git a/src/Misc/Master.h b/src/Misc/Master.h
@@ -16,6 +16,7 @@
#define MASTER_H
#include "../globals.h"
#include "Microtonal.h"
+#include <atomic>
#include <rtosc/automations.h>
#include <rtosc/savefile.h>
@@ -215,6 +216,8 @@ class Master
uint32_t last_beat = 0;
uint32_t last_ack = 0;
private:
+ std::atomic<bool> run_osc_in_use = { false };
+
float sysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS];
float sysefxsend[NUM_SYS_EFX][NUM_SYS_EFX];
int keyshift;