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;...@@ -8,7 +8,7 @@ const Allocator = std.mem.Allocator;
8pub fn Group(comptime ReturnType: type) type {8pub fn Group(comptime ReturnType: type) type {
9 return struct {9 return struct {
10 frame_stack: Stack,10 frame_stack: Stack,
11 alloc_stack: Stack,11 alloc_stack: AllocStack,
12 lock: Lock,12 lock: Lock,
13 allocator: *Allocator,13 allocator: *Allocator,
1414
...@@ -19,11 +19,17 @@ pub fn Group(comptime ReturnType: type) type {...@@ -19,11 +19,17 @@ pub fn Group(comptime ReturnType: type) type {
19 else => void,19 else => void,
20 };20 };
21 const Stack = std.atomic.Stack(anyframe->ReturnType);21 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
23 pub fn init(allocator: *Allocator) Self {29 pub fn init(allocator: *Allocator) Self {
24 return Self{30 return Self{
25 .frame_stack = Stack.init(),31 .frame_stack = Stack.init(),
26 .alloc_stack = Stack.init(),32 .alloc_stack = AllocStack.init(),
27 .lock = Lock.init(),33 .lock = Lock.init(),
28 .allocator = allocator,34 .allocator = allocator,
29 };35 };
...@@ -31,10 +37,12 @@ pub fn Group(comptime ReturnType: type) type {...@@ -31,10 +37,12 @@ pub fn Group(comptime ReturnType: type) type {
3137
32 /// Add a frame to the group. Thread-safe.38 /// Add a frame to the group. Thread-safe.
33 pub fn add(self: *Self, handle: anyframe->ReturnType) (error{OutOfMemory}!void) {39 pub fn add(self: *Self, handle: anyframe->ReturnType) (error{OutOfMemory}!void) {
34 const node = try self.allocator.create(Stack.Node);40 const node = try self.allocator.create(AllocStack.Node);
35 node.* = Stack.Node{41 node.* = AllocStack.Node{
36 .next = undefined,42 .next = undefined,
37 .data = handle,43 .data = Node{
44 .handle = handle,
45 },
38 };46 };
39 self.alloc_stack.push(node);47 self.alloc_stack.push(node);
40 }48 }
...@@ -48,6 +56,24 @@ pub fn Group(comptime ReturnType: type) type {...@@ -48,6 +56,24 @@ pub fn Group(comptime ReturnType: type) type {
48 self.frame_stack.push(node);56 self.frame_stack.push(node);
49 }57 }
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
51 /// Wait for all the calls and promises of the group to complete.77 /// Wait for all the calls and promises of the group to complete.
52 /// Thread-safe.78 /// Thread-safe.
53 /// Safe to call any number of times.79 /// Safe to call any number of times.
...@@ -67,8 +93,7 @@ pub fn Group(comptime ReturnType: type) type {...@@ -67,8 +93,7 @@ pub fn Group(comptime ReturnType: type) type {
67 }93 }
68 }94 }
69 while (self.alloc_stack.pop()) |node| {95 while (self.alloc_stack.pop()) |node| {
70 const handle = node.data;96 const handle = node.data.handle;
71 self.allocator.destroy(node);
72 if (Error == void) {97 if (Error == void) {
73 await handle;98 await handle;
74 } else {99 } else {
...@@ -76,6 +101,8 @@ pub fn Group(comptime ReturnType: type) type {...@@ -76,6 +101,8 @@ pub fn Group(comptime ReturnType: type) type {
76 result = err;101 result = err;
77 };102 };
78 }103 }
104 self.allocator.free(node.data.bytes);
105 self.allocator.destroy(node);
79 }106 }
80 return result;107 return result;
81 }108 }