diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-02-28 20:42:34 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-28 20:42:34 -0800 |
| commit | 9550db33cbb7dadd555842ef6d7214660e2b00d6 (patch) | |
| tree | ffcf41a01dc8a55f06f5a630ed174550be33dad3 /lib/std | |
| parent | a5a3ad4f956bae1ca0e5a49de2e9ac7145170039 (diff) | |
| parent | d3d3e55fae2299d1ff594c77da2f1f41f44ab525 (diff) | |
| download | zig-9550db33cbb7dadd555842ef6d7214660e2b00d6.tar.gz zig-9550db33cbb7dadd555842ef6d7214660e2b00d6.zip | |
Merge pull request #8097 from LemonBoy/thread-spawn-order
std: Swap arguments in Thread.spawn
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/Thread.zig | 26 | ||||
| -rw-r--r-- | lib/std/Thread/AutoResetEvent.zig | 4 | ||||
| -rw-r--r-- | lib/std/Thread/Mutex.zig | 2 | ||||
| -rw-r--r-- | lib/std/Thread/ResetEvent.zig | 4 | ||||
| -rw-r--r-- | lib/std/Thread/StaticResetEvent.zig | 4 | ||||
| -rw-r--r-- | lib/std/atomic/queue.zig | 4 | ||||
| -rw-r--r-- | lib/std/atomic/stack.zig | 4 | ||||
| -rw-r--r-- | lib/std/event/loop.zig | 10 | ||||
| -rw-r--r-- | lib/std/fs/test.zig | 2 | ||||
| -rw-r--r-- | lib/std/net/test.zig | 4 | ||||
| -rw-r--r-- | lib/std/once.zig | 4 | ||||
| -rw-r--r-- | lib/std/os/test.zig | 14 |
12 files changed, 48 insertions, 34 deletions
diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig index 77277bd154..b9a69d151f 100644 --- a/lib/std/Thread.zig +++ b/lib/std/Thread.zig @@ -165,18 +165,32 @@ pub const SpawnError = error{ Unexpected, }; -/// caller must call wait on the returned thread -/// fn startFn(@TypeOf(context)) T -/// where T is u8, noreturn, void, or !void -/// caller must call wait on the returned thread -pub fn spawn(context: anytype, comptime startFn: anytype) SpawnError!*Thread { +// Given `T`, the type of the thread startFn, extract the expected type for the +// context parameter. +fn SpawnContextType(comptime T: type) type { + const TI = @typeInfo(T); + if (TI != .Fn) + @compileError("expected function type, found " ++ @typeName(T)); + + if (TI.Fn.args.len != 1) + @compileError("expected function with single argument, found " ++ @typeName(T)); + + return TI.Fn.args[0].arg_type orelse + @compileError("cannot use a generic function as thread startFn"); +} + +/// Spawns a new thread executing startFn, returning an handle for it. +/// Caller must call wait on the returned thread. +/// The `startFn` function must take a single argument of type T and return a +/// value of type u8, noreturn, void or !void. +/// The `context` parameter is of type T and is passed to the spawned thread. +pub fn spawn(comptime startFn: anytype, context: SpawnContextType(@TypeOf(startFn))) SpawnError!*Thread { if (builtin.single_threaded) @compileError("cannot spawn thread when building in single-threaded mode"); // TODO compile-time call graph analysis to determine stack upper bound // https://github.com/ziglang/zig/issues/157 const default_stack_size = 16 * 1024 * 1024; const Context = @TypeOf(context); - comptime assert(@typeInfo(@TypeOf(startFn)).Fn.args[0].arg_type.? == Context); if (std.Target.current.os.tag == .windows) { const WinThread = struct { diff --git a/lib/std/Thread/AutoResetEvent.zig b/lib/std/Thread/AutoResetEvent.zig index 8b8b5658bf..0726dc794a 100644 --- a/lib/std/Thread/AutoResetEvent.zig +++ b/lib/std/Thread/AutoResetEvent.zig @@ -220,8 +220,8 @@ test "basic usage" { }; var context = Context{}; - const send_thread = try std.Thread.spawn(&context, Context.sender); - const recv_thread = try std.Thread.spawn(&context, Context.receiver); + const send_thread = try std.Thread.spawn(Context.sender, &context); + const recv_thread = try std.Thread.spawn(Context.receiver, &context); send_thread.wait(); recv_thread.wait(); diff --git a/lib/std/Thread/Mutex.zig b/lib/std/Thread/Mutex.zig index 94711bcda0..e7d11954bf 100644 --- a/lib/std/Thread/Mutex.zig +++ b/lib/std/Thread/Mutex.zig @@ -299,7 +299,7 @@ test "basic usage" { const thread_count = 10; var threads: [thread_count]*std.Thread = undefined; for (threads) |*t| { - t.* = try std.Thread.spawn(&context, worker); + t.* = try std.Thread.spawn(worker, &context); } for (threads) |t| t.wait(); diff --git a/lib/std/Thread/ResetEvent.zig b/lib/std/Thread/ResetEvent.zig index 622f9be98e..439fb0db40 100644 --- a/lib/std/Thread/ResetEvent.zig +++ b/lib/std/Thread/ResetEvent.zig @@ -281,7 +281,7 @@ test "basic usage" { var context: Context = undefined; try context.init(); defer context.deinit(); - const receiver = try std.Thread.spawn(&context, Context.receiver); + const receiver = try std.Thread.spawn(Context.receiver, &context); defer receiver.wait(); context.sender(); @@ -290,7 +290,7 @@ test "basic usage" { // https://github.com/ziglang/zig/issues/7009 var timed = Context.init(); defer timed.deinit(); - const sleeper = try std.Thread.spawn(&timed, Context.sleeper); + const sleeper = try std.Thread.spawn(Context.sleeper, &timed); defer sleeper.wait(); try timed.timedWaiter(); } diff --git a/lib/std/Thread/StaticResetEvent.zig b/lib/std/Thread/StaticResetEvent.zig index 6d90d7cf9a..07a8e50c16 100644 --- a/lib/std/Thread/StaticResetEvent.zig +++ b/lib/std/Thread/StaticResetEvent.zig @@ -379,7 +379,7 @@ test "basic usage" { }; var context = Context{}; - const receiver = try std.Thread.spawn(&context, Context.receiver); + const receiver = try std.Thread.spawn(Context.receiver, &context); defer receiver.wait(); context.sender(); @@ -388,7 +388,7 @@ test "basic usage" { // https://github.com/ziglang/zig/issues/7009 var timed = Context.init(); defer timed.deinit(); - const sleeper = try std.Thread.spawn(&timed, Context.sleeper); + const sleeper = try std.Thread.spawn(Context.sleeper, &timed); defer sleeper.wait(); try timed.timedWaiter(); } diff --git a/lib/std/atomic/queue.zig b/lib/std/atomic/queue.zig index f5f63944ab..4e427a1669 100644 --- a/lib/std/atomic/queue.zig +++ b/lib/std/atomic/queue.zig @@ -216,11 +216,11 @@ test "std.atomic.Queue" { var putters: [put_thread_count]*std.Thread = undefined; for (putters) |*t| { - t.* = try std.Thread.spawn(&context, startPuts); + t.* = try std.Thread.spawn(startPuts, &context); } var getters: [put_thread_count]*std.Thread = undefined; for (getters) |*t| { - t.* = try std.Thread.spawn(&context, startGets); + t.* = try std.Thread.spawn(startGets, &context); } for (putters) |t| diff --git a/lib/std/atomic/stack.zig b/lib/std/atomic/stack.zig index d55a8f81a3..4096c27354 100644 --- a/lib/std/atomic/stack.zig +++ b/lib/std/atomic/stack.zig @@ -123,11 +123,11 @@ test "std.atomic.stack" { } else { var putters: [put_thread_count]*std.Thread = undefined; for (putters) |*t| { - t.* = try std.Thread.spawn(&context, startPuts); + t.* = try std.Thread.spawn(startPuts, &context); } var getters: [put_thread_count]*std.Thread = undefined; for (getters) |*t| { - t.* = try std.Thread.spawn(&context, startGets); + t.* = try std.Thread.spawn(startGets, &context); } for (putters) |t| diff --git a/lib/std/event/loop.zig b/lib/std/event/loop.zig index 912f99e961..878cea4aa6 100644 --- a/lib/std/event/loop.zig +++ b/lib/std/event/loop.zig @@ -185,7 +185,7 @@ pub const Loop = struct { errdefer self.deinitOsData(); if (!builtin.single_threaded) { - self.fs_thread = try Thread.spawn(self, posixFsRun); + self.fs_thread = try Thread.spawn(posixFsRun, self); } errdefer if (!builtin.single_threaded) { self.posixFsRequest(&self.fs_end_request); @@ -264,7 +264,7 @@ pub const Loop = struct { } } while (extra_thread_index < extra_thread_count) : (extra_thread_index += 1) { - self.extra_threads[extra_thread_index] = try Thread.spawn(self, workerRun); + self.extra_threads[extra_thread_index] = try Thread.spawn(workerRun, self); } }, .macos, .freebsd, .netbsd, .dragonfly, .openbsd => { @@ -329,7 +329,7 @@ pub const Loop = struct { } } while (extra_thread_index < extra_thread_count) : (extra_thread_index += 1) { - self.extra_threads[extra_thread_index] = try Thread.spawn(self, workerRun); + self.extra_threads[extra_thread_index] = try Thread.spawn(workerRun, self); } }, .windows => { @@ -378,7 +378,7 @@ pub const Loop = struct { } } while (extra_thread_index < extra_thread_count) : (extra_thread_index += 1) { - self.extra_threads[extra_thread_index] = try Thread.spawn(self, workerRun); + self.extra_threads[extra_thread_index] = try Thread.spawn(workerRun, self); } }, else => {}, @@ -798,7 +798,7 @@ pub const Loop = struct { .event = std.Thread.AutoResetEvent{}, .is_running = true, // Must be last so that it can read the other state, such as `is_running`. - .thread = try std.Thread.spawn(self, DelayQueue.run), + .thread = try std.Thread.spawn(DelayQueue.run, self), }; } diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index e9f28a0b60..0e2d296bb7 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -762,7 +762,7 @@ test "open file with exclusive lock twice, make sure it waits" { try evt.init(); defer evt.deinit(); - const t = try std.Thread.spawn(S.C{ .dir = &tmp.dir, .evt = &evt }, S.checkFn); + const t = try std.Thread.spawn(S.checkFn, S.C{ .dir = &tmp.dir, .evt = &evt }); defer t.wait(); const SLEEP_TIMEOUT_NS = 10 * std.time.ns_per_ms; diff --git a/lib/std/net/test.zig b/lib/std/net/test.zig index 10a9c4e18b..4470d17aeb 100644 --- a/lib/std/net/test.zig +++ b/lib/std/net/test.zig @@ -161,7 +161,7 @@ test "listen on a port, send bytes, receive bytes" { } }; - const t = try std.Thread.spawn(server.listen_address, S.clientFn); + const t = try std.Thread.spawn(S.clientFn, server.listen_address); defer t.wait(); var client = try server.accept(); @@ -285,7 +285,7 @@ test "listen on a unix socket, send bytes, receive bytes" { } }; - const t = try std.Thread.spawn({}, S.clientFn); + const t = try std.Thread.spawn(S.clientFn, {}); defer t.wait(); var client = try server.accept(); diff --git a/lib/std/once.zig b/lib/std/once.zig index efa99060d3..79d273b86a 100644 --- a/lib/std/once.zig +++ b/lib/std/once.zig @@ -59,11 +59,11 @@ test "Once executes its function just once" { defer for (threads) |handle| handle.wait(); for (threads) |*handle| { - handle.* = try std.Thread.spawn(@as(u8, 0), struct { + handle.* = try std.Thread.spawn(struct { fn thread_fn(x: u8) void { global_once.call(); } - }.thread_fn); + }.thread_fn, 0); } } diff --git a/lib/std/os/test.zig b/lib/std/os/test.zig index f08d4d58fa..c8cef38d5d 100644 --- a/lib/std/os/test.zig +++ b/lib/std/os/test.zig @@ -317,7 +317,7 @@ test "std.Thread.getCurrentId" { if (builtin.single_threaded) return error.SkipZigTest; var thread_current_id: Thread.Id = undefined; - const thread = try Thread.spawn(&thread_current_id, testThreadIdFn); + const thread = try Thread.spawn(testThreadIdFn, &thread_current_id); const thread_id = thread.handle(); thread.wait(); if (Thread.use_pthreads) { @@ -336,10 +336,10 @@ test "spawn threads" { var shared_ctx: i32 = 1; - const thread1 = try Thread.spawn({}, start1); - const thread2 = try Thread.spawn(&shared_ctx, start2); - const thread3 = try Thread.spawn(&shared_ctx, start2); - const thread4 = try Thread.spawn(&shared_ctx, start2); + const thread1 = try Thread.spawn(start1, {}); + const thread2 = try Thread.spawn(start2, &shared_ctx); + const thread3 = try Thread.spawn(start2, &shared_ctx); + const thread4 = try Thread.spawn(start2, &shared_ctx); thread1.wait(); thread2.wait(); @@ -367,8 +367,8 @@ test "cpu count" { test "thread local storage" { if (builtin.single_threaded) return error.SkipZigTest; - const thread1 = try Thread.spawn({}, testTls); - const thread2 = try Thread.spawn({}, testTls); + const thread1 = try Thread.spawn(testTls, {}); + const thread2 = try Thread.spawn(testTls, {}); testTls({}); thread1.wait(); thread2.wait(); |
