fix: make autosave_running atomic to fix data race in thread shutdown

Co-authored-by: aider (deepseek/deepseek-coder) <aider@aider.chat>
This commit is contained in:
Loic Coenen
2026-05-03 21:14:30 +00:00
parent d5082fc856
commit 5d2acbe1fb

11
fs.c
View File

@@ -10,6 +10,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <dirent.h> #include <dirent.h>
#include <time.h> #include <time.h>
#include <stdatomic.h>
// ============================================================ // ============================================================
// Auto-save thread // Auto-save thread
@@ -18,7 +19,7 @@
static pthread_t autosave_thread; static pthread_t autosave_thread;
static pthread_mutex_t autosave_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t autosave_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t autosave_cond = PTHREAD_COND_INITIALIZER; static pthread_cond_t autosave_cond = PTHREAD_COND_INITIALIZER;
static volatile bool autosave_running = false; static atomic_bool autosave_running = false;
static volatile bool autosave_pending = false; static volatile bool autosave_pending = false;
static time_t last_autosave_time = 0; static time_t last_autosave_time = 0;
@@ -35,11 +36,11 @@ static void ensure_autosave_dir(void) {
static void* autosave_thread_func(void *arg) { static void* autosave_thread_func(void *arg) {
(void)arg; (void)arg;
while (autosave_running) { while (atomic_load(&autosave_running)) {
pthread_mutex_lock(&autosave_mutex); pthread_mutex_lock(&autosave_mutex);
// Wait for trigger or shutdown // Wait for trigger or shutdown
while (autosave_running && !autosave_pending) { while (atomic_load(&autosave_running) && !autosave_pending) {
struct timespec ts; struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts); clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += 5; // Wake up every 5 seconds to check ts.tv_sec += 5; // Wake up every 5 seconds to check
@@ -101,14 +102,14 @@ static void* autosave_thread_func(void *arg) {
} }
void fs_init(void) { void fs_init(void) {
autosave_running = true; atomic_store(&autosave_running, true);
autosave_pending = false; autosave_pending = false;
ensure_autosave_dir(); ensure_autosave_dir();
pthread_create(&autosave_thread, NULL, autosave_thread_func, NULL); pthread_create(&autosave_thread, NULL, autosave_thread_func, NULL);
} }
void fs_cleanup(void) { void fs_cleanup(void) {
autosave_running = false; atomic_store(&autosave_running, false);
pthread_cond_signal(&autosave_cond); pthread_cond_signal(&autosave_cond);
pthread_join(autosave_thread, NULL); pthread_join(autosave_thread, NULL);
} }