Merge pull request #6337 from andzdroid/patch-2

nbio: fix op re-use
This commit is contained in:
Laytan
2026-02-27 21:18:31 +01:00
committed by GitHub
2 changed files with 55 additions and 0 deletions

View File

@@ -336,6 +336,12 @@ __tick :: proc(l: ^Event_Loop, timeout: time.Duration) -> General_Error {
if .Error in event.flags { curr._impl.flags += {.Error} }
if .EOF in event.flags { curr._impl.flags += {.EOF} }
curr._impl.result = event.data
// Remove refs to the list in case the operation would still block and `add_pending`
// is executed on it again.
curr._impl.prev = nil
curr._impl.next = nil
handle_completed(curr)
}
}
@@ -1154,6 +1160,8 @@ stat_exec :: proc(op: ^Operation) {
add_pending :: proc(op: ^Operation, filter: kq.Filter, ident: uintptr) {
debug("adding pending", op.type)
assert(op._impl.next == nil)
assert(op._impl.prev == nil)
op._impl.flags += {.For_Kernel}
_, val, just_inserted, err := map_entry(&op.l.submitted, Queue_Identifier{ ident = ident, filter = filter })

View File

@@ -256,3 +256,50 @@ wake_up :: proc(t: ^testing.T) {
}
}
}
// Tests that if multiple accepts are queued, and a dial comes in which completes one of them,
// the rest are queued again properly.
@(test)
still_pending :: proc(t: ^testing.T) {
if event_loop_guard(t) {
testing.set_fail_timeout(t, time.Minute)
sock, ep := open_next_available_local_port(t)
defer nbio.close(sock)
N :: 3
State :: struct {
accepted: int,
}
state: State
on_accept :: proc(op: ^nbio.Operation, t: ^testing.T, state: ^State) {
ev(t, op.accept.err, nil)
state.accepted += 1
nbio.close(op.accept.client)
}
on_dial :: proc(op: ^nbio.Operation, t: ^testing.T) {
ev(t, op.dial.err, nil)
nbio.close(op.dial.socket)
}
for _ in 0..<N {
nbio.accept_poly2(sock, t, &state, on_accept)
}
nbio.dial_poly(ep, t, on_dial)
for state.accepted < 1 {
ev(t, nbio.tick(), nil)
}
for _ in 0..<N-1 {
nbio.dial_poly(ep, t, on_dial)
}
ev(t, nbio.run(), nil)
ev(t, state.accepted, N)
}
}