Fix Ctrl+C not terminating the C backend
Two issues: - signal() on Linux sets SA_RESTART by default, causing sleep(1) to be restarted after the signal handler runs. Switch to sigaction() with no SA_RESTART flag and replace sleep(1) with pause() so the main thread wakes and exits immediately on SIGINT/SIGTERM. - close(sock_fd) is not guaranteed to unblock another thread blocked in accept() on that fd. Add shutdown(SHUT_RDWR) before close() in socket_server_stop() for both the listening socket and the client socket, which reliably wakes blocked accept() and read() calls. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -164,7 +164,7 @@ static void on_disconnect(void *ctx) {
|
|||||||
|
|
||||||
/* ── Signal handler ───────────────────────────────────────────────── */
|
/* ── Signal handler ───────────────────────────────────────────────── */
|
||||||
|
|
||||||
static volatile int g_running = 1;
|
static volatile sig_atomic_t g_running = 1;
|
||||||
static void on_signal(int sig) { (void)sig; g_running = 0; }
|
static void on_signal(int sig) { (void)sig; g_running = 0; }
|
||||||
|
|
||||||
/* ── Entry point ──────────────────────────────────────────────────── */
|
/* ── Entry point ──────────────────────────────────────────────────── */
|
||||||
@@ -190,12 +190,14 @@ int main(int argc, char *argv[]) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
signal(SIGINT, on_signal);
|
struct sigaction sa = { .sa_handler = on_signal, .sa_flags = 0 };
|
||||||
signal(SIGTERM, on_signal);
|
sigemptyset(&sa.sa_mask);
|
||||||
|
sigaction(SIGINT, &sa, NULL);
|
||||||
|
sigaction(SIGTERM, &sa, NULL);
|
||||||
|
|
||||||
fprintf(stderr, "midi-sequencer ready, waiting for node client\n");
|
fprintf(stderr, "midi-sequencer ready, waiting for node client\n");
|
||||||
while (g_running) {
|
while (g_running) {
|
||||||
sleep(1);
|
pause(); /* sleep until any signal; returns immediately on SIGINT/SIGTERM */
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "midi-sequencer shutting down\n");
|
fprintf(stderr, "midi-sequencer shutting down\n");
|
||||||
|
|||||||
@@ -127,9 +127,15 @@ int socket_server_start(Socket_Server *srv, const char *path,
|
|||||||
|
|
||||||
void socket_server_stop(Socket_Server *srv) {
|
void socket_server_stop(Socket_Server *srv) {
|
||||||
atomic_store(&srv->running, 0);
|
atomic_store(&srv->running, 0);
|
||||||
|
/* shutdown before close to reliably unblock accept() in accept_thread */
|
||||||
|
shutdown(srv->sock_fd, SHUT_RDWR);
|
||||||
close(srv->sock_fd);
|
close(srv->sock_fd);
|
||||||
int fd = atomic_exchange(&srv->client_fd, -1);
|
int fd = atomic_exchange(&srv->client_fd, -1);
|
||||||
if (fd >= 0) close(fd);
|
if (fd >= 0) {
|
||||||
|
/* shutdown before close to reliably unblock read() in read_thread */
|
||||||
|
shutdown(fd, SHUT_RDWR);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
pthread_join(srv->accept_thread, NULL);
|
pthread_join(srv->accept_thread, NULL);
|
||||||
pthread_join(srv->read_thread, NULL);
|
pthread_join(srv->read_thread, NULL);
|
||||||
pthread_mutex_destroy(&srv->write_mutex);
|
pthread_mutex_destroy(&srv->write_mutex);
|
||||||
|
|||||||
Reference in New Issue
Block a user