diff options
| author | Alexandros Naskos <alex_naskos@hotmail.com> | 2020-10-01 15:57:02 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-10-01 15:57:02 +0300 |
| commit | beda6f2299d918cb5ed3444f18e985dc7de448b0 (patch) | |
| tree | e525fdf2e0abc09e7d88f88532515368ecc2a966 /lib/std | |
| parent | b358c281718a2f6437612fb73590a4992242cf52 (diff) | |
| parent | 16f041970007d997d67ee2e15f0eba1053204808 (diff) | |
| download | zig-beda6f2299d918cb5ed3444f18e985dc7de448b0.tar.gz zig-beda6f2299d918cb5ed3444f18e985dc7de448b0.zip | |
Merge pull request #6455 from kristoff-it/event-loop-go
add runDetached to event loop
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/event/loop.zig | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/lib/std/event/loop.zig b/lib/std/event/loop.zig index 2ed9f938d8..cb0aa63dbe 100644 --- a/lib/std/event/loop.zig +++ b/lib/std/event/loop.zig @@ -647,6 +647,29 @@ pub const Loop = struct { } } + /// Runs the provided function asynchonously, similarly to Go's "go" operator. + /// `func` must return void and it can be an async function. + fn runDetached(self: *Loop, alloc: *mem.Allocator, comptime func: anytype, args: anytype) error{OutOfMemory}!void { + if (!std.io.is_async) @compileError("Can't use runDetached in non-async mode!"); + if (@TypeOf(@call(.{}, func, args)) != void) { + @compileError("`func` must not have a return value"); + } + + const Wrapper = struct { + const Args = @TypeOf(args); + fn run(func_args: Args, loop: *Loop, allocator: *mem.Allocator) void { + loop.yield(); + const result = @call(.{}, func, func_args); + suspend { + allocator.destroy(@frame()); + } + } + }; + + var run_frame = try alloc.create(@Frame(Wrapper.run)); + run_frame.* = async Wrapper.run(args, self, alloc); + } + /// Yielding lets the event loop run, starting any unstarted async operations. /// Note that async operations automatically start when a function yields for any other reason, /// for example, when async I/O is performed. This function is intended to be used only when @@ -1493,3 +1516,33 @@ fn testEventLoop2(h: anyframe->i32, did_it: *bool) void { testing.expect(value == 1234); did_it.* = true; } + +var testRunDetachedData: usize = 0; +test "std.event.Loop - runDetached" { + // https://github.com/ziglang/zig/issues/1908 + if (builtin.single_threaded) return error.SkipZigTest; + if (!std.io.is_async) return error.SkipZigTest; + if (true) { + // https://github.com/ziglang/zig/issues/4922 + return error.SkipZigTest; + } + + var loop: Loop = undefined; + try loop.initMultiThreaded(); + defer loop.deinit(); + + // Schedule the execution, won't actually start until we start the + // event loop. + try loop.runDetached(std.testing.allocator, testRunDetached, .{}); + + // Now we can start the event loop. The function will return only + // after all tasks have been completed, allowing us to synchonize + // with the previous runDetached. + loop.run(); + + testing.expect(testRunDetachedData == 1); +} + +fn testRunDetached() void { + testRunDetachedData += 1; +} |
