add mutex locks around modifications to child process array
All checks were successful
Generic zig build / build (push) Successful in 1m4s
All checks were successful
Generic zig build / build (push) Successful in 1m4s
This commit is contained in:
parent
b509b88569
commit
885283e486
1 changed files with 13 additions and 0 deletions
13
src/main.zig
13
src/main.zig
|
|
@ -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) = .{},
|
||||||
|
child_processes_mutex: std.Thread.Mutex = .{},
|
||||||
reclaiming: std.atomic.Value(bool) = std.atomic.Value(bool).init(false),
|
reclaiming: std.atomic.Value(bool) = std.atomic.Value(bool).init(false),
|
||||||
|
|
||||||
const max_children = 5;
|
const max_children = 5;
|
||||||
|
|
@ -52,6 +53,10 @@ const SpeechHandler = struct {
|
||||||
}
|
}
|
||||||
fn exec(self: *SpeechHandler, text: []const u8) !void {
|
fn exec(self: *SpeechHandler, text: []const u8) !void {
|
||||||
const program = self.exec_program.?; // should only be called when exec_program is not null
|
const program = self.exec_program.?; // should only be called when exec_program is not null
|
||||||
|
|
||||||
|
self.child_processes_mutex.lock();
|
||||||
|
defer self.child_processes_mutex.unlock();
|
||||||
|
|
||||||
// We need to be able to clean up at some point in the future, but we don't
|
// We need to be able to clean up at some point in the future, but we don't
|
||||||
// care about these processes otherwise
|
// care about these processes otherwise
|
||||||
const process = try self.allocator.create(Process);
|
const process = try self.allocator.create(Process);
|
||||||
|
|
@ -76,6 +81,10 @@ const SpeechHandler = struct {
|
||||||
// This code should present that
|
// This code should present that
|
||||||
if (self.reclaiming.cmpxchgStrong(false, true, .acquire, .acquire)) |_| return;
|
if (self.reclaiming.cmpxchgStrong(false, true, .acquire, .acquire)) |_| return;
|
||||||
defer self.reclaiming.store(false, .release);
|
defer self.reclaiming.store(false, .release);
|
||||||
|
|
||||||
|
self.child_processes_mutex.lock();
|
||||||
|
defer self.child_processes_mutex.unlock();
|
||||||
|
|
||||||
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;
|
||||||
|
|
@ -266,6 +275,10 @@ fn signalAction(sig: i32, info: *const std.posix.siginfo_t, _: ?*anyopaque) call
|
||||||
if (sig == std.posix.SIG.CHLD) {
|
if (sig == std.posix.SIG.CHLD) {
|
||||||
const pid = info.fields.common.first.piduid.pid;
|
const pid = info.fields.common.first.piduid.pid;
|
||||||
std.log.debug("SIGCHLD on pid {d}", .{pid});
|
std.log.debug("SIGCHLD on pid {d}", .{pid});
|
||||||
|
|
||||||
|
handler.child_processes_mutex.lock();
|
||||||
|
defer handler.child_processes_mutex.unlock();
|
||||||
|
|
||||||
for (handler.child_processes.items) |proc| {
|
for (handler.child_processes.items) |proc| {
|
||||||
if (proc.child) |child| {
|
if (proc.child) |child| {
|
||||||
if (child.id == pid) {
|
if (child.id == pid) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue