fix: prevent hang in scene add/remove test and fix unsafe scene copy

Co-authored-by: aider (deepseek/deepseek-reasoner) <aider@aider.chat>
This commit is contained in:
Loic Coenen
2026-05-10 18:34:26 +00:00
parent 4dfb7a87c1
commit 1ba98fc768
2 changed files with 65 additions and 11 deletions

View File

@@ -1135,34 +1135,79 @@ static int write_fifo(const char *cmd) {
static int test_scene_add_remove(void) {
printf("Test: scene add/remove via FIFO\n");
fflush(stdout);
pid_t pid = start_looper();
if (pid < 0) return 1;
/* add a scene */
printf(" sending scene_add...\n");
fflush(stdout);
if (!write_fifo("scene_add\n")) {
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
kill(pid, SIGTERM);
for (int tries = 0; tries < 20; tries++) {
int wstatus;
pid_t ret = waitpid(pid, &wstatus, WNOHANG);
if (ret == pid) break;
if (ret < 0) break;
safe_usleep(100000);
}
kill(pid, SIGKILL); waitpid(pid, NULL, 0);
fprintf(stderr, " FAIL: cannot write to FIFO\n");
return 1;
}
safe_usleep(50000); /* allow processing */
/* verify that scene_next works (doesn't crash) */
printf(" sending scene_next...\n");
fflush(stdout);
if (!write_fifo("scene_next\n")) {
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
kill(pid, SIGTERM);
for (int tries = 0; tries < 20; tries++) {
int wstatus;
pid_t ret = waitpid(pid, &wstatus, WNOHANG);
if (ret == pid) break;
if (ret < 0) break;
safe_usleep(100000);
}
kill(pid, SIGKILL); waitpid(pid, NULL, 0);
return 1;
}
safe_usleep(50000);
/* remove scene */
printf(" sending scene_remove...\n");
fflush(stdout);
if (!write_fifo("scene_remove\n")) {
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
kill(pid, SIGTERM);
for (int tries = 0; tries < 20; tries++) {
int wstatus;
pid_t ret = waitpid(pid, &wstatus, WNOHANG);
if (ret == pid) break;
if (ret < 0) break;
safe_usleep(100000);
}
kill(pid, SIGKILL); waitpid(pid, NULL, 0);
return 1;
}
safe_usleep(50000);
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
printf(" PASS (no crash means success)\n");
return 0;
/* kill with timeout */
kill(pid, SIGTERM);
for (int tries = 0; tries < 20; tries++) {
int wstatus;
pid_t ret = waitpid(pid, &wstatus, WNOHANG);
if (ret == pid) {
printf(" PASS (scene add/remove, looper exited)\n");
fflush(stdout);
return 0;
}
if (ret < 0) {
perror("waitpid");
break;
}
safe_usleep(100000); /* 100ms */
}
kill(pid, SIGKILL);
waitpid(pid, NULL, 0);
fprintf(stderr, " FAIL: looper did not exit in time\n");
return 1;
}
static int test_scene_next_prev_midi(void) {