mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-03-08 01:04:43 +01:00
std.Io: fix Select cancel deadlock with no tasks
This commit is contained in:
parent
ac24e6caf5
commit
0a412853aa
2 changed files with 14 additions and 6 deletions
|
|
@ -1446,11 +1446,8 @@ pub fn Select(comptime U: type) type {
|
|||
/// Threadsafe.
|
||||
pub fn cancel(s: *S) ?U {
|
||||
const io = s.io;
|
||||
if (s.group.token.load(.acquire)) |token| {
|
||||
io.vtable.groupCancel(io.userdata, &s.group, token);
|
||||
assert(s.group.token.raw == null);
|
||||
s.queue.close(io);
|
||||
}
|
||||
s.group.cancel(io);
|
||||
s.queue.close(io);
|
||||
return s.queue.getOneUncancelable(io) catch |err| switch (err) {
|
||||
error.Closed => return null,
|
||||
};
|
||||
|
|
@ -1855,7 +1852,7 @@ pub const TypeErasedQueue = struct {
|
|||
/// there is space in the buffer. However, existing elements of the
|
||||
/// queue are retrieved before `error.Closed` is returned.
|
||||
///
|
||||
/// Threadsafe.
|
||||
/// Idempotent. Threadsafe.
|
||||
pub fn close(q: *TypeErasedQueue, io: Io) void {
|
||||
q.mutex.lockUncancelable(io);
|
||||
defer q.mutex.unlock(io);
|
||||
|
|
|
|||
|
|
@ -937,3 +937,14 @@ test "Select with empty buffer, no deadlock" {
|
|||
};
|
||||
assert((try select.await()) == .sleeper);
|
||||
}
|
||||
|
||||
test "Select.cancel with no tasks, no deadlock" {
|
||||
const io = testing.io;
|
||||
|
||||
const U = union(enum) {
|
||||
nothing: void,
|
||||
also_nothing: void,
|
||||
};
|
||||
var select: Io.Select(U) = .init(io, &.{});
|
||||
try expectEqual(null, select.cancel());
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue