diff --git a/src/main.zig b/src/main.zig index a06a6cf..123bb1b 100644 --- a/src/main.zig +++ b/src/main.zig @@ -12,33 +12,27 @@ const options = @import("build_options"); const args = zocket.deps.args; -// TODO: switch vars/consts/params to snake_case - /// Resolves the config path, then delegates to `run`. /// /// Allocator strategy: /// - Debug builds use `DebugAllocator`, which tracks every allocation and /// panics/exits on leaks or double-frees. -/// - Release builds use `c_allocator` for C ABI interop. +/// - Release builds use `smp_allocator`. pub fn main(init: std.process.Init) !void { const debug = builtin.mode == .Debug; const io = init.io; var gpa: std.heap.DebugAllocator(.{}) = .init; - defer _ = gpa.deinit(); - defer if (debug) - { - if (gpa.detectLeaks() != 0) std.process.exit(1); - }; + defer if (gpa.deinit() == .leak) std.process.exit(1); - const allocator = if (debug) gpa.allocator() else std.heap.c_allocator; + const allocator = if (debug) gpa.allocator() else std.heap.smp_allocator; - var tmp_arena = std.heap.ArenaAllocator.init(allocator); + var tmp_arena = std.heap.ArenaAllocator.init(allocator); var arena_live = true; + errdefer _ = zocket.memory.deinitIfLive(&tmp_arena, &arena_live); const tmp_allocator = tmp_arena.allocator(); - errdefer zocket.memory.deinitIfLive(&tmp_arena, &arena_live); var parser = try args.ArgumentParser.init(tmp_allocator, .{ .name = "zocket", @@ -67,7 +61,7 @@ pub fn main(init: std.process.Init) !void break :path try allocator.dupe(u8, tmp_path); }; - zocket.memory.deinitIfLive(&tmp_arena, &arena_live); + _ = zocket.memory.deinitIfLive(&tmp_arena, &arena_live); try run(io, allocator, path); } @@ -88,7 +82,7 @@ fn run(io: std.Io, allocator: std.mem.Allocator, path: []const u8) !void error.AccessDenied => "Permission denied reading", else => "Unexpected error opening", }; - std.log.err("{s}: '{s}' ({any})\n", .{ msg, path, err }); + std.log.err("{s}: '{s}' ({any})", .{ msg, path, err }); std.process.exit(1); }; defer parsed.deinit(); diff --git a/src/memory/util.zig b/src/memory/util.zig index e5e4791..7246854 100644 --- a/src/memory/util.zig +++ b/src/memory/util.zig @@ -1,27 +1,27 @@ const std = @import("std"); -/// Deinitializes `allocator` only if it is still live. +/// Deinitializes `resource` only if it is still live. /// -/// Pass a pointer to the original allocator owner, such as an -/// `ArenaAllocator` or `DebugAllocator`. +/// Pass a pointer to the original allocator owner, +/// such as an `ArenaAllocator`. /// /// If `live` is `true`, calls `allocator.deinit()` and then sets /// `live` to `false`, preventing a later cleanup path from attempting /// to deinitialize the same allocator again. /// -/// The return value of `deinit()` is discarded. -pub fn deinitIfLive(allocator: anytype, live: *bool) void +/// The return value of `deinit()` is returned from the function. +pub fn deinitIfLive(resource: anytype, live: *bool) ?@TypeOf(resource.deinit()) { comptime { - const T = @TypeOf(allocator); + const T = @TypeOf(resource); if (@typeInfo(T) != .pointer) @compileError("deinitIfLive expects a pointer!"); if (T == std.mem.Allocator) @compileError("deinitIfLive expects a pointer to an allocator owner, not std.mem.Allocator!"); } - if (live.*) { - _ = allocator.deinit(); - live.* = false; - } + if (!live.*) return null; + + live.* = false; + return resource.deinit(); }