fix: use atomic operations for thread-safe state access

Co-authored-by: aider (deepseek/deepseek-reasoner) <aider@aider.chat>
This commit is contained in:
Loic Coenen
2026-05-07 20:51:06 +00:00
parent f0b58a9684
commit 9d43b15b46

View File

@@ -5,6 +5,7 @@
#include <signal.h> #include <signal.h>
#include <jack/jack.h> #include <jack/jack.h>
#include <jack/midiport.h> #include <jack/midiport.h>
#include <stdatomic.h>
typedef enum { typedef enum {
STATE_IDLE, STATE_IDLE,
@@ -13,7 +14,7 @@ typedef enum {
STATE_PAUSED STATE_PAUSED
} looper_state; } looper_state;
static volatile looper_state current_state = STATE_IDLE; static atomic_int current_state = STATE_IDLE;
static jack_port_t *input_port; static jack_port_t *input_port;
static jack_port_t *output_port; static jack_port_t *output_port;
@@ -46,18 +47,19 @@ static int process(jack_nframes_t nframes, void *arg)
if ((ev.size >= 3) && ((ev.buffer[0] & 0xf0) == 0x90)) { if ((ev.size >= 3) && ((ev.buffer[0] & 0xf0) == 0x90)) {
unsigned char note = ev.buffer[1]; unsigned char note = ev.buffer[1];
if (note == 1) { if (note == 1) {
switch (current_state) { int cur_state = atomic_load(&current_state);
switch (cur_state) {
case STATE_IDLE: case STATE_IDLE:
current_state = STATE_RECORD; atomic_store(&current_state, STATE_RECORD);
break; break;
case STATE_RECORD: case STATE_RECORD:
current_state = STATE_LOOPING; atomic_store(&current_state, STATE_LOOPING);
break; break;
case STATE_LOOPING: case STATE_LOOPING:
current_state = STATE_PAUSED; atomic_store(&current_state, STATE_PAUSED);
break; break;
case STATE_PAUSED: case STATE_PAUSED:
current_state = STATE_LOOPING; atomic_store(&current_state, STATE_LOOPING);
break; break;
} }
} }
@@ -77,14 +79,16 @@ static int process(jack_nframes_t nframes, void *arg)
unsigned char msg = cev.buffer[0]; unsigned char msg = cev.buffer[0];
// real-time messages: Start (0xFA), Stop (0xFC), Continue (0xFB) // real-time messages: Start (0xFA), Stop (0xFC), Continue (0xFB)
if (msg == 0xFA) { // Start transport -> begin recording if idle if (msg == 0xFA) { // Start transport -> begin recording if idle
if (current_state == STATE_IDLE) { int s = atomic_load(&current_state);
current_state = STATE_RECORD; if (s == STATE_IDLE) {
atomic_store(&current_state, STATE_RECORD);
} }
} else if (msg == 0xFC) { // Stop transport -> return to IDLE } else if (msg == 0xFC) { // Stop transport -> return to IDLE
current_state = STATE_IDLE; atomic_store(&current_state, STATE_IDLE);
} else if (msg == 0xFB) { // Continue transport -> resume looping (if paused) } else if (msg == 0xFB) { // Continue transport -> resume looping (if paused)
if (current_state == STATE_PAUSED) { int s = atomic_load(&current_state);
current_state = STATE_LOOPING; if (s == STATE_PAUSED) {
atomic_store(&current_state, STATE_LOOPING);
} }
} }
} }
@@ -104,7 +108,8 @@ static void jack_shutdown(void *arg)
static void sigusr1_handler(int signo) { static void sigusr1_handler(int signo) {
(void)signo; (void)signo;
int code = (int)current_state + 1; int state = atomic_load(&current_state);
int code = state + 1;
_exit(code); _exit(code);
} }