about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRobert Günzler <r@gnzler.io>2025-10-18 02:28:48 +0200
committerRobert Günzler <r@gnzler.io>2025-10-18 03:17:44 +0200
commit4a1a309d90e4161d65e93854df523e7308b028a6 (patch)
tree4eb2dfc6db4f8191c69c72ff26b1518ae9061913
parent98c4afd018532adc6b3c6011027f069541b82ee9 (diff)
downloadsite-4a1a309d90e4161d65e93854df523e7308b028a6.tar.gz
refactor thread pool code into generic helper
Signed-off-by: Robert Günzler <r@gnzler.io>
-rw-r--r--src/exe.zig70
1 files changed, 53 insertions, 17 deletions
diff --git a/src/exe.zig b/src/exe.zig
index 63efd9a..56914b3 100644
--- a/src/exe.zig
+++ b/src/exe.zig
@@ -5,27 +5,63 @@ const fs = @import("fs.zig");
 
 const log = std.log.scoped(.exe);
 
+pub fn WaitPool(
+    comptime T: type,
+    comptime worker: anytype,
+) type {
+    return struct {
+        const Self = @This();
+
+        pub fn work(ctx: *Context, items: []const T, args: anytype) !void {
+            var wg: std.Thread.WaitGroup = undefined;
+            wg.reset();
+
+            var pool: std.Thread.Pool = undefined;
+            try pool.init(.{
+                .n_jobs = (try std.Thread.getCpuCount()) - 1,
+                .allocator = ctx.allocator(),
+            });
+            defer pool.deinit();
+
+            for (items) |*item| {
+                // the inline struct trick is a workardoun for Thread.Pool::spawn not
+                // accepting functions that can error:
+                // https://github.com/ziglang/zig/issues/18810
+                try pool.spawn(struct {
+                    fn func(
+                        wwg: *std.Thread.WaitGroup,
+                        wctx: *Context,
+                        witem: *const T,
+                        wargs: anytype,
+                    ) void {
+                        wwg.start();
+                        defer wwg.finish();
+
+                        const result = @call(
+                            .auto,
+                            worker,
+                            .{ wctx, witem.* } ++ wargs,
+                        );
+
+                        result catch |err|
+                            std.log.err("worker failed with: {}", .{err});
+                    }
+                }.func, .{ &wg, ctx, item, args });
+            }
+
+            pool.waitAndWork(&wg);
+        }
+    };
+}
+
 pub fn runPandoc(ctx: *Context) !void {
     ctx.progress_start("Processing markdown files");
     defer ctx.progress_end();
 
-    var pool: std.Thread.Pool = undefined;
-    try pool.init(.{
-        .n_jobs = (try std.Thread.getCpuCount()) - 1,
-        .allocator = ctx.allocator(),
-    });
-    defer pool.deinit();
-
-    for (ctx.markdown.items) |*page| {
-        // the inline struct trick is a workardoun for Thread.Pool::spawn not
-        // accepting functions that can error:
-        // https://github.com/ziglang/zig/issues/18810
-        try pool.spawn(struct {
-            fn worker(worker_ctx: *Context, worker_page: *const []const u8) void {
-                pandocWorker(worker_ctx, worker_page.*) catch |err| std.log.err("pandoc worker failed with: {}", .{err});
-            }
-        }.worker, .{ ctx, page });
-    }
+    try WaitPool(
+        []const u8,
+        pandocWorker,
+    ).work(ctx, ctx.markdown.items, .{});
 
     log.info("Processed {d} markdown files.", .{ctx.markdown.items.len});
 }