prevent race condition between speech recognition and SIGCHLD

This commit is contained in:
Emil Lerch 2025-09-15 19:45:18 -07:00
parent aabe2f1908
commit f32e4401c8
Signed by: lobo
GPG key ID: A7B62D657EF764F8

View file

@ -19,6 +19,7 @@ const SpeechHandler = struct {
recoverable_error_count: u32 = 0, recoverable_error_count: u32 = 0,
exec_program: ?[]const u8 = null, exec_program: ?[]const u8 = null,
child_processes: std.ArrayList(*Process) = .{}, child_processes: std.ArrayList(*Process) = .{},
reclaiming: std.atomic.Value(bool) = std.atomic.Value(bool).init(false),
const max_children = 5; const max_children = 5;
const Process = struct { child: ?*std.process.Child, start: i64, id: std.process.Child.Id }; // why id? const Process = struct { child: ?*std.process.Child, start: i64, id: std.process.Child.Id }; // why id?
@ -69,6 +70,10 @@ const SpeechHandler = struct {
} }
fn reclaimProcessesPosix(self: *SpeechHandler, reap_all: bool) !void { fn reclaimProcessesPosix(self: *SpeechHandler, reap_all: bool) !void {
// We could end up called by two threads at the same time (via SIGCHLD and an actual speech event)
// This code should present that
if (self.reclaiming.cmpxchgStrong(false, true, .acquire, .acquire)) |_| return;
defer self.reclaiming.store(false, .release);
if (!reap_all and self.child_processes.items.len <= max_children) return; if (!reap_all and self.child_processes.items.len <= max_children) return;
std.log.debug("Reclaiming memory from {s} processes", .{if (reap_all) "ALL" else "completed"}); std.log.debug("Reclaiming memory from {s} processes", .{if (reap_all) "ALL" else "completed"});
if (self.child_processes.items.len == 0) return; if (self.child_processes.items.len == 0) return;