nbio: fix op re-use

This commit is contained in:
andzdroid
2026-02-26 00:30:27 +00:00
parent 61d53212dd
commit 334a554de3
2 changed files with 77 additions and 0 deletions

View File

@@ -1154,6 +1154,8 @@ stat_exec :: proc(op: ^Operation) {
add_pending :: proc(op: ^Operation, filter: kq.Filter, ident: uintptr) {
debug("adding pending", op.type)
op._impl.next = nil
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,78 @@ wake_up :: proc(t: ^testing.T) {
}
}
}
@(test)
reused_ops :: proc(t: ^testing.T) {
if event_loop_guard(t) {
testing.set_fail_timeout(t, time.Minute)
@static payload := [4]byte{'P', 'I', 'N', 'G'}
sock, ep := open_next_available_local_port(t)
State :: struct {
listener: nbio.TCP_Socket,
accepts: [4]^nbio.Operation,
client: nbio.TCP_Socket,
server_client: nbio.TCP_Socket,
recv_buf: [4]byte,
recv_done: bool,
}
state := State{
listener = sock,
}
on_accept :: proc(op: ^nbio.Operation, t: ^testing.T, state: ^State, slot: int) {
if state.recv_done {
nbio.close(op.accept.client)
return
}
ev(t, op.accept.err, nil)
if state.server_client == 0 {
state.server_client = op.accept.client
nbio.recv_poly2(state.server_client, {state.recv_buf[:]}, t, state, on_recv, timeout=0)
}
state.accepts[slot] = nbio.accept_poly3(op.accept.socket, t, state, slot, on_accept, timeout=nbio.NO_TIMEOUT)
}
on_recv :: proc(op: ^nbio.Operation, t: ^testing.T, state: ^State) {
ev(t, op.recv.err, nil)
ev(t, op.recv.received, 4)
ev(t, state.recv_buf, payload)
state.recv_done = true
for accept in state.accepts {
if accept != nil {
nbio.remove(accept)
}
}
nbio.close(state.server_client)
nbio.close(state.client)
nbio.close(state.listener)
}
on_dial :: proc(op: ^nbio.Operation, t: ^testing.T, state: ^State) {
ev(t, op.dial.err, nil)
state.client = op.dial.socket
nbio.send_poly2(state.client, {payload[:]}, t, state, on_send)
}
on_send :: proc(op: ^nbio.Operation, t: ^testing.T, state: ^State) {
ev(t, op.send.err, nil)
ev(t, op.send.sent, (4))
}
for slot in 0 ..< 4 {
state.accepts[slot] = nbio.accept_poly3(sock, t, &state, slot, on_accept, timeout=nbio.NO_TIMEOUT)
}
ev(t, nbio.tick(0), nil)
nbio.dial_poly2(ep, t, &state, on_dial)
ev(t, nbio.run(), nil)
e(t, state.recv_done)
}
}