@@ -14,7 +14,8 @@ const TaskStatus = struct {
14
14
done : std.Thread.ResetEvent = .{},
15
15
priority : Priority ,
16
16
ctx : * anyopaque ,
17
- func : * const fn (ctx : * anyopaque ) void ,
17
+ runFn : * const fn (ctx : * anyopaque ) void ,
18
+ deinitFn : * const fn (ctx : * anyopaque , allocator : std.mem.Allocator ) void ,
18
19
};
19
20
20
21
const Queue = std .DoublyLinkedList (TaskStatus );
@@ -45,24 +46,37 @@ pub fn deinit(self: *Self) void {
45
46
std .debug .assert (self .num_tasks == 0 );
46
47
}
47
48
48
- pub fn createTask (self : * Self , priority : Priority , func : anytype , ctx : anytype ) ! Task {
49
+ pub fn createTask (self : * Self , priority : Priority , comptime func : anytype , args : anytype ) ! Task {
49
50
self .queue_mutex .lock ();
50
51
defer self .queue_mutex .unlock ();
51
52
52
53
const task = try self .allocator .create (Queue .Node );
53
54
errdefer self .allocator .destroy (task );
54
55
55
- const Wrapper = struct {
56
- pub fn run (c : * anyopaque ) void {
57
- @call (.auto , func , .{@as (@TypeOf (ctx ), @ptrCast (@alignCast (c )))});
56
+ const Args = @TypeOf (args );
57
+ const Closure = struct {
58
+ arguments : Args ,
59
+
60
+ fn deinit (ctx : * anyopaque , allocator : std.mem.Allocator ) void {
61
+ const closure : * @This () = @ptrCast (@alignCast (ctx ));
62
+ allocator .destroy (closure );
63
+ }
64
+
65
+ fn run (ctx : * anyopaque ) void {
66
+ const closure : * @This () = @ptrCast (@alignCast (ctx ));
67
+ @call (.auto , func , closure .arguments );
58
68
}
59
69
};
60
70
71
+ const closure = try self .allocator .create (Closure );
72
+ errdefer self .allocator .destroy (closure );
73
+
61
74
task .* = .{
62
75
.data = .{
63
76
.priority = priority ,
64
- .ctx = ctx ,
65
- .func = Wrapper .run ,
77
+ .ctx = closure ,
78
+ .runFn = Closure .run ,
79
+ .deinitFn = Closure .deinit ,
66
80
},
67
81
};
68
82
task .data .done .set ();
@@ -81,6 +95,7 @@ pub fn destroyTask(self: *Self, task: Task) void {
81
95
82
96
task .data .done .wait ();
83
97
98
+ task .data .deinitFn (task .data .ctx , self .allocator );
84
99
self .allocator .destroy (task );
85
100
86
101
std .debug .assert (self .num_tasks > 0 );
@@ -141,7 +156,7 @@ fn workerThreadFunc(self: *Self) void {
141
156
const task = self .getTaskToRun () orelse break ;
142
157
defer self .markAsDone (task );
143
158
144
- task .data .func (task .data .ctx );
159
+ task .data .runFn (task .data .ctx );
145
160
}
146
161
}
147
162
0 commit comments