diff options
| author | Robert Günzler <r@gnzler.io> | 2025-10-03 19:01:17 +0200 |
|---|---|---|
| committer | Robert Günzler <r@gnzler.io> | 2025-10-04 18:41:55 +0200 |
| commit | c775f0d0341c8c0389d8d9cbb4760ac5c03e0899 (patch) | |
| tree | fd2e996fece093d4985724977313b91f5f647529 /src/main.zig | |
| parent | 4487d75818d36085e3540934f609a997d256f20c (diff) | |
| download | site-c775f0d0341c8c0389d8d9cbb4760ac5c03e0899.tar.gz | |
make context thread-safe
by wrapping arena in ThreadSafeAllocator and using a mutex around the context node stack Signed-off-by: Robert Günzler <r@gnzler.io>
Diffstat (limited to 'src/main.zig')
| -rw-r--r-- | src/main.zig | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/src/main.zig b/src/main.zig index 0b4c73a..faa37aa 100644 --- a/src/main.zig +++ b/src/main.zig @@ -18,7 +18,11 @@ pub const std_options = std.Options{ pub const Context = struct { arena: std.heap.ArenaAllocator, - progress_nodes: std.ArrayList(std.Progress.Node), + arena_mx: std.Thread.Mutex, + alloc: std.heap.ThreadSafeAllocator, + + progress_nodes: std.ArrayListUnmanaged(std.Progress.Node), + progress_nodes_mx: std.Thread.Mutex, pages: std.ArrayListUnmanaged([]const u8), markdown: std.ArrayListUnmanaged([]const u8), @@ -48,12 +52,21 @@ pub const Context = struct { const self = try parent_alloc.create(Context); self.* = .{ .arena = std.heap.ArenaAllocator.init(parent_alloc), - .progress_nodes = try .initCapacity(self.allocator(), 10), + .arena_mx = .{}, + .alloc = undefined, + .progress_nodes = .{}, + .progress_nodes_mx = .{}, .pages = .{}, .markdown = .{}, }; + // create thread safe allocator + self.alloc = std.heap.ThreadSafeAllocator{ + .child_allocator = self.arena.allocator(), + .mutex = self.arena_mx, + }; // create root progress node - self.progress_nodes.appendAssumeCapacity( + try self.progress_nodes.append( + self.allocator(), std.Progress.start(.{ .root_name = "" }), ); return self; @@ -61,22 +74,26 @@ pub const Context = struct { fn destroy(self: *Context) void { self.progress_end(); - self.progress_nodes.deinit(); + self.progress_nodes.deinit(self.allocator()); self.arena.deinit(); self.arena.child_allocator.destroy(self); } pub fn allocator(self: *Context) std.mem.Allocator { - return self.arena.allocator(); + return self.alloc.allocator(); } // progress handling pub fn progress_start(self: *Context, name: []const u8) void { + self.progress_nodes_mx.lock(); const new = self.progress_nodes.getLast().start(name, 0); - self.progress_nodes.appendAssumeCapacity(new); + self.progress_nodes.append(self.allocator(), new) catch @panic("insufficient memory"); + self.progress_nodes_mx.unlock(); } pub fn progress_end(self: *Context) void { + self.progress_nodes_mx.lock(); const current = self.progress_nodes.pop() orelse return; + self.progress_nodes_mx.unlock(); current.end(); } }; @@ -172,7 +189,7 @@ const Cli = struct { }; pub fn main() !void { - var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + var gpa = std.heap.GeneralPurposeAllocator(.{}).init; const allocator = gpa.allocator(); defer _ = gpa.deinit(); |