feat: add address sanitizer, persistent FIFO fds, and latency test
This commit is contained in:
committed by
Loic Coenen (aider)
parent
0537263a7a
commit
dd67576c45
@@ -1,5 +1,5 @@
|
||||
CC = gcc
|
||||
CFLAGS = -Wall -Wextra -Wpedantic -std=c11 -Isrc -I../engine/src
|
||||
CFLAGS = -Wall -Wextra -Wpedantic -std=c11 -Isrc -I../engine/src -fsanitize=address -fno-omit-frame-pointer
|
||||
CARLA_INC = -I/usr/include/carla -I/usr/include/carla/includes
|
||||
CARLA_LIB = -L/usr/lib/carla -Wl,-rpath,/usr/lib/carla -lcarla_standalone2
|
||||
|
||||
@@ -20,10 +20,10 @@ TEST_INTEGRATION_BIN = test_integration
|
||||
all: looper-client test_status_parse
|
||||
|
||||
looper-client: src/main.c src/tui.c $(PLUGINS_OBJ) $(CARLA_OBJ) $(CLIENT_CMD_OBJ) $(SCRIPT_OBJ) $(LOG_OBJ)
|
||||
$(CC) $(CFLAGS) $(CARLA_INC) -o $@ $^ $(CARLA_LIB) -ljack -lncurses
|
||||
$(CC) $(CFLAGS) $(CARLA_INC) -fsanitize=address -o $@ $^ $(CARLA_LIB) -ljack -lncurses
|
||||
|
||||
test_status_parse: tests/test_status_parse.c $(PLUGINS_OBJ) $(CARLA_OBJ) $(CLIENT_CMD_OBJ) $(SCRIPT_OBJ)
|
||||
$(CC) $(CFLAGS) $(CARLA_INC) -o test_status_parse tests/test_status_parse.c src/tui.c $(PLUGINS_OBJ) $(CARLA_OBJ) $(CLIENT_CMD_OBJ) $(SCRIPT_OBJ) $(CARLA_LIB) -ljack -lncurses
|
||||
test_status_parse: tests/test_status_parse.c $(PLUGINS_OBJ) $(CARLA_OBJ) $(CLIENT_CMD_OBJ) $(SCRIPT_OBJ) $(LOG_OBJ)
|
||||
$(CC) $(CFLAGS) $(CARLA_INC) -o test_status_parse tests/test_status_parse.c src/tui.c $(PLUGINS_OBJ) $(CARLA_OBJ) $(CLIENT_CMD_OBJ) $(SCRIPT_OBJ) $(LOG_OBJ) $(CARLA_LIB) -ljack -lncurses
|
||||
|
||||
# --- Plugin stubs (now real) ---
|
||||
$(PLUGINS_OBJ): src/plugins.c src/plugins.h
|
||||
@@ -84,7 +84,7 @@ TEST_CLIENT_OBJ = tests/test_client.o
|
||||
$(TEST_CLIENT_OBJ): tests/test_client.c src/tui.h
|
||||
$(CC) $(CFLAGS) $(CARLA_INC) -c -o $@ $<
|
||||
|
||||
$(TEST_CLIENT_BIN): $(TEST_CLIENT_OBJ) src/tui.c $(PLUGINS_OBJ) $(CARLA_OBJ) $(CLIENT_CMD_OBJ) $(SCRIPT_OBJ)
|
||||
$(TEST_CLIENT_BIN): $(TEST_CLIENT_OBJ) src/tui.c $(PLUGINS_OBJ) $(CARLA_OBJ) $(CLIENT_CMD_OBJ) $(SCRIPT_OBJ) $(LOG_OBJ)
|
||||
$(CC) $(CFLAGS) $(CARLA_INC) -o $@ $^ $(CARLA_LIB) -ljack -lncurses
|
||||
|
||||
# --- Carla host tests ---
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <CarlaHost.h>
|
||||
#include <CarlaBackend.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "carla_host.h"
|
||||
|
||||
@@ -137,21 +138,25 @@ int carla_connect(int id, const char *port_name, const char *looper_port) {
|
||||
if (!port_name || !looper_port) return -1;
|
||||
if (!jack_client) return -1;
|
||||
|
||||
fprintf(stderr, "CARLA_CONNECT: plugin_id=%d conn_count=%d port=%s looper=%s\n",
|
||||
id, conn_count, port_name, looper_port);
|
||||
// Real JACK port connection
|
||||
int ret = jack_connect(jack_client, looper_port, port_name);
|
||||
if (ret != 0) return -1;
|
||||
|
||||
// Store the connection so we can disconnect it later
|
||||
if (conn_count < MAX_CONNECTIONS) {
|
||||
connections[conn_count].plugin_id = id;
|
||||
strncpy(connections[conn_count].plugin_port, port_name,
|
||||
sizeof(connections[conn_count].plugin_port) - 1);
|
||||
connections[conn_count].plugin_port[sizeof(connections[conn_count].plugin_port) - 1] = '\0';
|
||||
strncpy(connections[conn_count].looper_port, looper_port,
|
||||
sizeof(connections[conn_count].looper_port) - 1);
|
||||
connections[conn_count].looper_port[sizeof(connections[conn_count].looper_port) - 1] = '\0';
|
||||
conn_count++;
|
||||
if (conn_count >= MAX_CONNECTIONS) {
|
||||
fprintf(stderr, "WARN: connection array full, refusing new connection\n");
|
||||
return -1;
|
||||
}
|
||||
connections[conn_count].plugin_id = id;
|
||||
strncpy(connections[conn_count].plugin_port, port_name,
|
||||
sizeof(connections[conn_count].plugin_port) - 1);
|
||||
connections[conn_count].plugin_port[sizeof(connections[conn_count].plugin_port) - 1] = '\0';
|
||||
strncpy(connections[conn_count].looper_port, looper_port,
|
||||
sizeof(connections[conn_count].looper_port) - 1);
|
||||
connections[conn_count].looper_port[sizeof(connections[conn_count].looper_port) - 1] = '\0';
|
||||
conn_count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,34 +24,29 @@
|
||||
static bool engine_running = false;
|
||||
static bool debug_mode = false;
|
||||
|
||||
/* Persistent FIFO fds – open once and reuse */
|
||||
static int cmd_fifo_fd = -1;
|
||||
static int status_fifo_fd = -1;
|
||||
|
||||
/* ---------- FIFO command helper ---------- */
|
||||
int send_command(const char *cmd) {
|
||||
if (debug_mode)
|
||||
fprintf(stderr, "DEBUG: send_command(%s)\n", cmd);
|
||||
const char *fifo_path = getenv("LOOPER_CMD_FIFO");
|
||||
if (!fifo_path) fifo_path = "/tmp/looper_cmd";
|
||||
|
||||
// Retry open up to 5 times with a short sleep, blocking mode
|
||||
int fd = -1;
|
||||
for (int attempt = 0; attempt < 5 && fd < 0; attempt++) {
|
||||
fd = open(fifo_path, O_WRONLY); // blocking – waits for reader
|
||||
if (fd < 0) {
|
||||
if (errno == ENXIO && attempt < 4)
|
||||
{
|
||||
struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 };
|
||||
nanosleep(&ts, NULL);
|
||||
}
|
||||
else
|
||||
break;
|
||||
if (cmd_fifo_fd < 0) {
|
||||
const char *fifo_path = getenv("LOOPER_CMD_FIFO");
|
||||
if (!fifo_path) fifo_path = "/tmp/looper_cmd";
|
||||
cmd_fifo_fd = open(fifo_path, O_WRONLY);
|
||||
if (cmd_fifo_fd < 0) {
|
||||
perror("open cmd FIFO");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (fd < 0) return -1;
|
||||
|
||||
size_t len = strlen(cmd);
|
||||
int n = write(fd, cmd, len);
|
||||
int n = write(cmd_fifo_fd, cmd, len);
|
||||
if (n == (int)len && cmd[len-1] != '\n')
|
||||
write(fd, "\n", 1);
|
||||
close(fd);
|
||||
write(cmd_fifo_fd, "\n", 1);
|
||||
return (n >= 0) ? 0 : -1;
|
||||
}
|
||||
|
||||
@@ -254,10 +249,12 @@ static bool in_colon = false;
|
||||
|
||||
/* Read the status FIFO once and update cell_state array */
|
||||
static void tui_read_status(void) {
|
||||
int fd = open(STATUS_FIFO, O_RDONLY | O_NONBLOCK);
|
||||
if (fd < 0) return;
|
||||
char buf[256];
|
||||
int n = read(fd, buf, sizeof(buf)-1);
|
||||
if (status_fifo_fd < 0) {
|
||||
status_fifo_fd = open(STATUS_FIFO, O_RDONLY | O_NONBLOCK);
|
||||
if (status_fifo_fd < 0) return;
|
||||
}
|
||||
char buf[4096];
|
||||
int n = read(status_fifo_fd, buf, sizeof(buf)-1);
|
||||
if (n > 0) {
|
||||
buf[n] = '\0';
|
||||
char *line = buf;
|
||||
@@ -274,7 +271,7 @@ static void tui_read_status(void) {
|
||||
if (nl) { *nl = '\n'; line = nl + 1; } else break;
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
/* keep fd open */
|
||||
}
|
||||
|
||||
void tui_run(void) {
|
||||
@@ -310,7 +307,14 @@ void tui_run(void) {
|
||||
}
|
||||
|
||||
/* redraw grid (status may have changed – no extra key needed) */
|
||||
draw_grid();
|
||||
{
|
||||
struct timespec t1, t2;
|
||||
clock_gettime(CLOCK_MONOTONIC, &t1);
|
||||
draw_grid();
|
||||
clock_gettime(CLOCK_MONOTONIC, &t2);
|
||||
double ms = (t2.tv_sec - t1.tv_sec)*1000.0 + (t2.tv_nsec - t1.tv_nsec)/1000000.0;
|
||||
if (ms > 200) log_msg("SLOW draw_grid: %f ms", ms);
|
||||
}
|
||||
|
||||
int chc = getch();
|
||||
|
||||
@@ -470,6 +474,14 @@ void tui_run(void) {
|
||||
}
|
||||
|
||||
void tui_cleanup(void) {
|
||||
if (cmd_fifo_fd >= 0) {
|
||||
close(cmd_fifo_fd);
|
||||
cmd_fifo_fd = -1;
|
||||
}
|
||||
if (status_fifo_fd >= 0) {
|
||||
close(status_fifo_fd);
|
||||
status_fifo_fd = -1;
|
||||
}
|
||||
if (yank_buffer.clip_indices) free(yank_buffer.clip_indices);
|
||||
/* free script note allocations */
|
||||
script_cleanup();
|
||||
|
||||
Reference in New Issue
Block a user