fix: use atomic operations for thread-safe state access
Co-authored-by: aider (deepseek/deepseek-reasoner) <aider@aider.chat>
This commit is contained in:
29
src/main.c
29
src/main.c
@@ -5,6 +5,7 @@
|
||||
#include <signal.h>
|
||||
#include <jack/jack.h>
|
||||
#include <jack/midiport.h>
|
||||
#include <stdatomic.h>
|
||||
|
||||
typedef enum {
|
||||
STATE_IDLE,
|
||||
@@ -13,7 +14,7 @@ typedef enum {
|
||||
STATE_PAUSED
|
||||
} 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 *output_port;
|
||||
@@ -46,18 +47,19 @@ static int process(jack_nframes_t nframes, void *arg)
|
||||
if ((ev.size >= 3) && ((ev.buffer[0] & 0xf0) == 0x90)) {
|
||||
unsigned char note = ev.buffer[1];
|
||||
if (note == 1) {
|
||||
switch (current_state) {
|
||||
int cur_state = atomic_load(¤t_state);
|
||||
switch (cur_state) {
|
||||
case STATE_IDLE:
|
||||
current_state = STATE_RECORD;
|
||||
atomic_store(¤t_state, STATE_RECORD);
|
||||
break;
|
||||
case STATE_RECORD:
|
||||
current_state = STATE_LOOPING;
|
||||
atomic_store(¤t_state, STATE_LOOPING);
|
||||
break;
|
||||
case STATE_LOOPING:
|
||||
current_state = STATE_PAUSED;
|
||||
atomic_store(¤t_state, STATE_PAUSED);
|
||||
break;
|
||||
case STATE_PAUSED:
|
||||
current_state = STATE_LOOPING;
|
||||
atomic_store(¤t_state, STATE_LOOPING);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -77,14 +79,16 @@ static int process(jack_nframes_t nframes, void *arg)
|
||||
unsigned char msg = cev.buffer[0];
|
||||
// real-time messages: Start (0xFA), Stop (0xFC), Continue (0xFB)
|
||||
if (msg == 0xFA) { // Start transport -> begin recording if idle
|
||||
if (current_state == STATE_IDLE) {
|
||||
current_state = STATE_RECORD;
|
||||
int s = atomic_load(¤t_state);
|
||||
if (s == STATE_IDLE) {
|
||||
atomic_store(¤t_state, STATE_RECORD);
|
||||
}
|
||||
} else if (msg == 0xFC) { // Stop transport -> return to IDLE
|
||||
current_state = STATE_IDLE;
|
||||
atomic_store(¤t_state, STATE_IDLE);
|
||||
} else if (msg == 0xFB) { // Continue transport -> resume looping (if paused)
|
||||
if (current_state == STATE_PAUSED) {
|
||||
current_state = STATE_LOOPING;
|
||||
int s = atomic_load(¤t_state);
|
||||
if (s == STATE_PAUSED) {
|
||||
atomic_store(¤t_state, STATE_LOOPING);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,7 +108,8 @@ static void jack_shutdown(void *arg)
|
||||
|
||||
static void sigusr1_handler(int signo) {
|
||||
(void)signo;
|
||||
int code = (int)current_state + 1;
|
||||
int state = atomic_load(¤t_state);
|
||||
int code = state + 1;
|
||||
_exit(code);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user