authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-11-07 09:06:22+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-07 13:26:49-05:00
log459a364a33def68dbd46bce0f25bbf41eb4b7d22
treeb4168a0efbcd295cd408ba7e35016b23b8aeefcf
parent3858a526e32cc661f7b0fdd0f40edb184d7c9209

allow Group to optionally manage function frames' memory


1 files changed, 34 insertions(+), 7 deletions(-)

lib/std/event/group.zig+34-7
......@@ -8,7 +8,7 @@ const Allocator = std.mem.Allocator;
88pub fn Group(comptime ReturnType: type) type {
99 return struct {
1010 frame_stack: Stack,
11 alloc_stack: Stack,
11 alloc_stack: AllocStack,
1212 lock: Lock,
1313 allocator: *Allocator,
1414
......@@ -19,11 +19,17 @@ pub fn Group(comptime ReturnType: type) type {
1919 else => void,
2020 };
2121 const Stack = std.atomic.Stack(anyframe->ReturnType);
22 const AllocStack = std.atomic.Stack(Node);
23
24 pub const Node = struct {
25 bytes: []const u8 = [0]u8{},
26 handle: anyframe->ReturnType,
27 };
2228
2329 pub fn init(allocator: *Allocator) Self {
2430 return Self{
2531 .frame_stack = Stack.init(),
26 .alloc_stack = Stack.init(),
32 .alloc_stack = AllocStack.init(),
2733 .lock = Lock.init(),
2834 .allocator = allocator,
2935 };
......@@ -31,10 +37,12 @@ pub fn Group(comptime ReturnType: type) type {
3137
3238 /// Add a frame to the group. Thread-safe.
3339 pub fn add(self: *Self, handle: anyframe->ReturnType) (error{OutOfMemory}!void) {
34 const node = try self.allocator.create(Stack.Node);
35 node.* = Stack.Node{
40 const node = try self.allocator.create(AllocStack.Node);
41 node.* = AllocStack.Node{
3642 .next = undefined,
37 .data = handle,
43 .data = Node{
44 .handle = handle,
45 },
3846 };
3947 self.alloc_stack.push(node);
4048 }
......@@ -48,6 +56,24 @@ pub fn Group(comptime ReturnType: type) type {
4856 self.frame_stack.push(node);
4957 }
5058
59 /// This is equivalent to adding a frame to the group but the memory of its frame is
60 /// allocated by the group and freed by `wait`.
61 /// `func` must be async and have return type `ReturnType`.
62 /// Thread-safe.
63 pub fn call(self: *Self, comptime func: var, args: ...) error{OutOfMemory}!void {
64 var frame = try self.allocator.create(@Frame(func));
65 const node = try self.allocator.create(AllocStack.Node);
66 node.* = AllocStack.Node{
67 .next = undefined,
68 .data = Node{
69 .handle = frame,
70 .bytes = @sliceToBytes((*[1]@Frame(func))(frame)[0..]),
71 },
72 };
73 frame.* = async func(args);
74 self.alloc_stack.push(node);
75 }
76
5177 /// Wait for all the calls and promises of the group to complete.
5278 /// Thread-safe.
5379 /// Safe to call any number of times.
......@@ -67,8 +93,7 @@ pub fn Group(comptime ReturnType: type) type {
6793 }
6894 }
6995 while (self.alloc_stack.pop()) |node| {
70 const handle = node.data;
71 self.allocator.destroy(node);
96 const handle = node.data.handle;
7297 if (Error == void) {
7398 await handle;
7499 } else {
......@@ -76,6 +101,8 @@ pub fn Group(comptime ReturnType: type) type {
76101 result = err;
77102 };
78103 }
104 self.allocator.free(node.data.bytes);
105 self.allocator.destroy(node);
79106 }
80107 return result;
81108 }