aboutsummaryrefslogtreecommitdiff
path: root/lib/std/event
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-10-07 00:46:05 -0700
committerAndrew Kelley <andrew@ziglang.org>2020-10-07 00:46:05 -0700
commitb5a36f676b1fd69f195d9f1eb6e35f3eb2f15946 (patch)
tree92ce1ffa64bc2d32d5ef73dce66daf3c8e893ee6 /lib/std/event
parentd6d05fc84d33c71434a1f8bae51ca5956e08cdf0 (diff)
parentf2d374e8465042fa5cb6bf2be7b9b086948f3a94 (diff)
downloadzig-b5a36f676b1fd69f195d9f1eb6e35f3eb2f15946.tar.gz
zig-b5a36f676b1fd69f195d9f1eb6e35f3eb2f15946.zip
Merge remote-tracking branch 'origin/master' into llvm11
Conflicts: cmake/Findllvm.cmake The llvm11 branch changed 10's to 11's and master branch added the "using LLVM_CONFIG_EXE" help message, so the resolution was to merge these changes together. I also added a check to make sure LLVM is built with AVR enabled, which is no longer an experimental target.
Diffstat (limited to 'lib/std/event')
-rw-r--r--lib/std/event/loop.zig55
1 files changed, 55 insertions, 0 deletions
diff --git a/lib/std/event/loop.zig b/lib/std/event/loop.zig
index 2ed9f938d8..226d5f1d52 100644
--- a/lib/std/event/loop.zig
+++ b/lib/std/event/loop.zig
@@ -647,6 +647,31 @@ pub const Loop = struct {
}
}
+ /// Runs the provided function asynchronously. The function's frame is allocated
+ /// with `allocator` and freed when the function returns.
+ /// `func` must return void and it can be an async function.
+ /// Yields to the event loop, running the function on the next tick.
+ pub 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 +1518,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;
+}