revert wake change

This commit is contained in:
kalsprite
2026-08-21 00:09:43 -07:00
parent bcf2dcd2f0
commit 6e690afaf1

View File

@@ -25,6 +25,11 @@ _Event_Loop :: struct {
thread: win.HANDLE,
completed: queue.Queue(^Operation),
completed_oob: Multi_Producer_Single_Consumer,
state: enum {
Working,
Waking,
Sleeping,
},
}
@(private="package")
@@ -163,8 +168,11 @@ __tick :: proc(l: ^Event_Loop, timeout: time.Duration) -> (err: General_Error) {
actual_timeout := compute_timeout(l, timeout, next_timeout)
if actual_timeout > 0 {
// Work may have been queued after the drain at the top of this tick,
// so check the queues once more before blocking.
sync.atomic_store_explicit(&l.state, .Sleeping, .Release)
// There could be a race condition where we go sleeping at the same time as things get queued
// and a wakeup isn't done because the state is not .Sleeping yet.
// So after sleeping we first check our queues.
for {
op := (^Operation)(mpsc_dequeue(&l.queue))
if op == nil { break }
@@ -196,6 +204,8 @@ __tick :: proc(l: ^Event_Loop, timeout: time.Duration) -> (err: General_Error) {
}
}
sync.atomic_store_explicit(&l.state, .Working, .Relaxed)
if actual_timeout > 0 {
// We may have just waited some time, lets update the current time.
l.now = time.now()
@@ -768,10 +778,10 @@ _associate_socket :: proc(socket: Any_Socket, l: ^Event_Loop) -> Association_Err
@(private="package")
_wake_up :: proc(l: ^Event_Loop) {
// Unconditional: an APC queued before the loop enters its alertable wait stays
// pending and is delivered as soon as that wait begins. Queueing it only once the
// loop is already asleep drops every wake sent while it is still awake.
win.QueueUserAPC(proc "system" (Parameter: win.ULONG_PTR) {}, l.thread, 0)
_, exchanged := sync.atomic_compare_exchange_strong(&l.state, .Sleeping, .Waking)
if exchanged {
win.QueueUserAPC(proc "system" (Parameter: win.ULONG_PTR) {}, l.thread, 0)
}
}
@(private="package")