diff options
| author | Timon Kruiper <timonkruiper@gmail.com> | 2020-09-23 11:41:31 +0200 |
|---|---|---|
| committer | Timon Kruiper <timonkruiper@gmail.com> | 2020-09-23 11:41:31 +0200 |
| commit | 0eed7ec9d51fe8c0dd22b72da0130ad9d31877d0 (patch) | |
| tree | edabf258c98ede7cb8d06cfae73e3e9142ac0a48 /lib/std/event/loop.zig | |
| parent | 58ee5f4e61cd9b7a9ba65798e2214efa3753a733 (diff) | |
| download | zig-0eed7ec9d51fe8c0dd22b72da0130ad9d31877d0.tar.gz zig-0eed7ec9d51fe8c0dd22b72da0130ad9d31877d0.zip | |
Eventloop: Fix deadlock in linux event loop implementation
A simple empty main with evented-io would not quit, because some
threads were still waiting to be resumed (by the os). The os.write to
the eventfd only wakes up one thread and thus there are multiple writes
needed to wake up all the other threads.
Diffstat (limited to 'lib/std/event/loop.zig')
| -rw-r--r-- | lib/std/event/loop.zig | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/lib/std/event/loop.zig b/lib/std/event/loop.zig index 2600b337b3..bc2eab3c90 100644 --- a/lib/std/event/loop.zig +++ b/lib/std/event/loop.zig @@ -687,9 +687,14 @@ pub const Loop = struct { switch (builtin.os.tag) { .linux => { - // writing 8 bytes to an eventfd cannot fail - const amt = os.write(self.os_data.final_eventfd, &wakeup_bytes) catch unreachable; - assert(amt == wakeup_bytes.len); + // writing to the eventfd will only wake up one thread, thus multiple writes + // are needed to wakeup all the threads + var i: usize = 0; + while (i < self.extra_threads.len + 1) : (i += 1) { + // writing 8 bytes to an eventfd cannot fail + const amt = os.write(self.os_data.final_eventfd, &wakeup_bytes) catch unreachable; + assert(amt == wakeup_bytes.len); + } return; }, .macosx, .freebsd, .netbsd, .dragonfly => { |
