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 <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(¤t_state);
|
||||||
|
switch (cur_state) {
|
||||||
case STATE_IDLE:
|
case STATE_IDLE:
|
||||||
current_state = STATE_RECORD;
|
atomic_store(¤t_state, STATE_RECORD);
|
||||||
break;
|
break;
|
||||||
case STATE_RECORD:
|
case STATE_RECORD:
|
||||||
current_state = STATE_LOOPING;
|
atomic_store(¤t_state, STATE_LOOPING);
|
||||||
break;
|
break;
|
||||||
case STATE_LOOPING:
|
case STATE_LOOPING:
|
||||||
current_state = STATE_PAUSED;
|
atomic_store(¤t_state, STATE_PAUSED);
|
||||||
break;
|
break;
|
||||||
case STATE_PAUSED:
|
case STATE_PAUSED:
|
||||||
current_state = STATE_LOOPING;
|
atomic_store(¤t_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(¤t_state);
|
||||||
current_state = STATE_RECORD;
|
if (s == STATE_IDLE) {
|
||||||
|
atomic_store(¤t_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(¤t_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(¤t_state);
|
||||||
current_state = STATE_LOOPING;
|
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) {
|
static void sigusr1_handler(int signo) {
|
||||||
(void)signo;
|
(void)signo;
|
||||||
int code = (int)current_state + 1;
|
int state = atomic_load(¤t_state);
|
||||||
|
int code = state + 1;
|
||||||
_exit(code);
|
_exit(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user