fix: remove data races by making save_load_running atomic and removing main thread engine_process_commands calls

Co-authored-by: aider (deepseek/deepseek-coder) <aider@aider.chat>
This commit is contained in:
Loic Coenen
2026-05-02 11:00:43 +00:00
parent da88493866
commit 6fb81aa322
2 changed files with 3 additions and 22 deletions

View File

@@ -300,7 +300,7 @@ void* save_load_thread_func(void *arg) {
// Create samples directory if it doesn't exist // Create samples directory if it doesn't exist
mkdir("samples", 0755); mkdir("samples", 0755);
while (engine->save_load_running) { while (atomic_load(&engine->save_load_running)) {
SaveLoadRequest req; SaveLoadRequest req;
int ret = save_load_queue_pop(&engine->save_load_queue, &req); int ret = save_load_queue_pop(&engine->save_load_queue, &req);
@@ -382,7 +382,7 @@ void* save_load_thread_func(void *arg) {
int engine_start_save_load_thread(Engine *engine) { int engine_start_save_load_thread(Engine *engine) {
if (!engine) return -1; if (!engine) return -1;
engine->save_load_running = true; atomic_store(&engine->save_load_running, true);
save_load_queue_init(&engine->save_load_queue); save_load_queue_init(&engine->save_load_queue);
if (pthread_create(&engine->save_load_thread, NULL, save_load_thread_func, engine) != 0) { if (pthread_create(&engine->save_load_thread, NULL, save_load_thread_func, engine) != 0) {
@@ -397,7 +397,7 @@ int engine_start_save_load_thread(Engine *engine) {
void engine_stop_save_load_thread(Engine *engine) { void engine_stop_save_load_thread(Engine *engine) {
if (!engine) return; if (!engine) return;
engine->save_load_running = false; atomic_store(&engine->save_load_running, false);
pthread_join(engine->save_load_thread, NULL); pthread_join(engine->save_load_thread, NULL);
} }

19
tui.c
View File

@@ -129,7 +129,6 @@ static void delete_clips(int *clip_indices, int count) {
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
engine_reset_clip(g_engine, clip_indices[i]); engine_reset_clip(g_engine, clip_indices[i]);
} }
engine_process_commands(g_engine);
} }
// Yank clips (store their indices) // Yank clips (store their indices)
@@ -172,7 +171,6 @@ static void paste_clips(void) {
engine_trigger_clip(g_engine, new_clip_idx); engine_trigger_clip(g_engine, new_clip_idx);
} }
} }
engine_process_commands(g_engine);
} }
// Set a mark at current position // Set a mark at current position
@@ -199,7 +197,6 @@ static void go_to_mark(char mark_char) {
static void play_next_scene(void) { static void play_next_scene(void) {
int next_row = (selected_row + 1) % GRID_ROWS; int next_row = (selected_row + 1) % GRID_ROWS;
engine_trigger_scene(g_engine, next_row); engine_trigger_scene(g_engine, next_row);
engine_process_commands(g_engine);
selected_row = next_row; selected_row = next_row;
} }
@@ -207,7 +204,6 @@ static void play_next_scene(void) {
static void play_prev_scene(void) { static void play_prev_scene(void) {
int prev_row = (selected_row - 1 + GRID_ROWS) % GRID_ROWS; int prev_row = (selected_row - 1 + GRID_ROWS) % GRID_ROWS;
engine_trigger_scene(g_engine, prev_row); engine_trigger_scene(g_engine, prev_row);
engine_process_commands(g_engine);
selected_row = prev_row; selected_row = prev_row;
} }
@@ -435,7 +431,6 @@ static void handle_mouse_event(MEVENT *event) {
int clip_idx = grid_to_clip_index(selected_row, selected_col); int clip_idx = grid_to_clip_index(selected_row, selected_col);
engine_trigger_clip(g_engine, clip_idx); engine_trigger_clip(g_engine, clip_idx);
engine_process_commands(g_engine);
} else if (event->bstate & BUTTON3_CLICKED) { } else if (event->bstate & BUTTON3_CLICKED) {
// Right click: select and reset clip // Right click: select and reset clip
selected_row = grid_row; selected_row = grid_row;
@@ -443,21 +438,18 @@ static void handle_mouse_event(MEVENT *event) {
int clip_idx = grid_to_clip_index(selected_row, selected_col); int clip_idx = grid_to_clip_index(selected_row, selected_col);
engine_reset_clip(g_engine, clip_idx); engine_reset_clip(g_engine, clip_idx);
engine_process_commands(g_engine);
} else if (event->bstate & BUTTON2_CLICKED) { } else if (event->bstate & BUTTON2_CLICKED) {
// Middle click: select and trigger scene // Middle click: select and trigger scene
selected_row = grid_row; selected_row = grid_row;
selected_col = grid_col; selected_col = grid_col;
engine_trigger_scene(g_engine, selected_row); engine_trigger_scene(g_engine, selected_row);
engine_process_commands(g_engine);
} else if (event->bstate & BUTTON1_DOUBLE_CLICKED) { } else if (event->bstate & BUTTON1_DOUBLE_CLICKED) {
// Double left click: select and trigger scene // Double left click: select and trigger scene
selected_row = grid_row; selected_row = grid_row;
selected_col = grid_col; selected_col = grid_col;
engine_trigger_scene(g_engine, selected_row); engine_trigger_scene(g_engine, selected_row);
engine_process_commands(g_engine);
} }
} }
@@ -641,7 +633,6 @@ void tui_run(Engine *engine) {
case 't': { case 't': {
int clip_idx = grid_to_clip_index(selected_row, selected_col); int clip_idx = grid_to_clip_index(selected_row, selected_col);
engine_trigger_clip(engine, clip_idx); engine_trigger_clip(engine, clip_idx);
engine_process_commands(engine);
break; break;
} }
@@ -649,7 +640,6 @@ void tui_run(Engine *engine) {
// Delete (reset) current clip // Delete (reset) current clip
int clip_idx = grid_to_clip_index(selected_row, selected_col); int clip_idx = grid_to_clip_index(selected_row, selected_col);
engine_reset_clip(engine, clip_idx); engine_reset_clip(engine, clip_idx);
engine_process_commands(engine);
break; break;
} }
@@ -669,7 +659,6 @@ void tui_run(Engine *engine) {
case 's': { case 's': {
// Trigger scene for current row // Trigger scene for current row
engine_trigger_scene(engine, selected_row); engine_trigger_scene(engine, selected_row);
engine_process_commands(engine);
break; break;
} }
@@ -686,7 +675,6 @@ void tui_run(Engine *engine) {
} }
QuantizeMode next = modes[(current + 1) % num_modes]; QuantizeMode next = modes[(current + 1) % num_modes];
engine_set_quantize_mode(engine, next); engine_set_quantize_mode(engine, next);
engine_process_commands(engine);
break; break;
} }
@@ -697,19 +685,16 @@ void tui_run(Engine *engine) {
} else { } else {
engine_set_quantize_threshold(engine, 0); engine_set_quantize_threshold(engine, 0);
} }
engine_process_commands(engine);
break; break;
} }
case ' ': { // Space bar - toggle play/pause case ' ': { // Space bar - toggle play/pause
engine_transport_toggle_play(engine); engine_transport_toggle_play(engine);
engine_process_commands(engine);
break; break;
} }
case 'S': { // Shift+S - stop transport case 'S': { // Shift+S - stop transport
engine_transport_stop(engine); engine_transport_stop(engine);
engine_process_commands(engine);
break; break;
} }
@@ -718,13 +703,11 @@ void tui_run(Engine *engine) {
ClockSource next = (current == CLOCK_SOURCE_INTERNAL) ? ClockSource next = (current == CLOCK_SOURCE_INTERNAL) ?
CLOCK_SOURCE_MIDI : CLOCK_SOURCE_INTERNAL; CLOCK_SOURCE_MIDI : CLOCK_SOURCE_INTERNAL;
engine_set_clock_source(engine, next); engine_set_clock_source(engine, next);
engine_process_commands(engine);
break; break;
} }
case 'x': case 'x':
engine_transport_stop(engine); engine_transport_stop(engine);
engine_process_commands(engine);
break; break;
case ':': { case ':': {
@@ -791,14 +774,12 @@ void tui_run(Engine *engine) {
case 'u': { case 'u': {
// Undo // Undo
engine_undo_action(engine); engine_undo_action(engine);
engine_process_commands(engine);
break; break;
} }
case 18: { // Ctrl+R (18 = 0x12) case 18: { // Ctrl+R (18 = 0x12)
// Redo // Redo
engine_redo_action(engine); engine_redo_action(engine);
engine_process_commands(engine);
break; break;
} }