Zebediah Figura (@zfigura) commented about dlls/ntoskrnl.exe/sync.c:
EnterCriticalSection( &sync_cs );
- if ((ret = timer->Header.Inserted)) - KeCancelTimer(timer); - + ret = timer->Header.Inserted; timer->Header.Inserted = TRUE; + timer->Header.SignalState = FALSE; + if (timer->Header.WaitListHead.Blink && !*((ULONG_PTR *)&timer->Header.WaitListHead.Flink)) + { + CloseHandle(timer->Header.WaitListHead.Blink); + timer->Header.WaitListHead.Blink = NULL; + }
if (!timer->TimerListEntry.Blink) timer->TimerListEntry.Blink = (void *)CreateThreadpoolTimer(ke_timer_complete_proc, timer, NULL);
I'm a bit concerned about this change, because my assumption—although I never tried to validate it—is that KeSetTimerEx() should probably act as a fence, i.e. it shouldn't be possible for an earlier callback to execute simultaneously or after it's returned. In this case that could result in a non-periodic DPC executing twice, which seems dangerous. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/1559#note_17732