mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-20 05:20:28 +00:00
nbio: put clearing of list nodes in proper place and simplify test
This commit is contained in:
@@ -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,8 +1160,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
|
||||
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 })
|
||||
|
||||
@@ -257,77 +257,49 @@ 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)
|
||||
reused_ops :: proc(t: ^testing.T) {
|
||||
still_pending :: 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)
|
||||
defer nbio.close(sock)
|
||||
|
||||
N :: 3
|
||||
|
||||
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,
|
||||
accepted: int,
|
||||
}
|
||||
state: State
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
on_accept :: proc(op: ^nbio.Operation, t: ^testing.T, state: ^State) {
|
||||
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)
|
||||
state.accepted += 1
|
||||
nbio.close(op.accept.client)
|
||||
}
|
||||
|
||||
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) {
|
||||
on_dial :: proc(op: ^nbio.Operation, t: ^testing.T) {
|
||||
ev(t, op.dial.err, nil)
|
||||
state.client = op.dial.socket
|
||||
nbio.send_poly2(state.client, {payload[:]}, t, state, on_send)
|
||||
nbio.close(op.dial.socket)
|
||||
}
|
||||
|
||||
on_send :: proc(op: ^nbio.Operation, t: ^testing.T, state: ^State) {
|
||||
ev(t, op.send.err, nil)
|
||||
ev(t, op.send.sent, (4))
|
||||
for _ in 0..<N {
|
||||
nbio.accept_poly2(sock, t, &state, on_accept)
|
||||
}
|
||||
|
||||
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_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)
|
||||
}
|
||||
|
||||
nbio.dial_poly2(ep, t, &state, on_dial)
|
||||
ev(t, nbio.run(), nil)
|
||||
e(t, state.recv_done)
|
||||
ev(t, state.accepted, N)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user