Zebediah Figura (@zfigura) commented about dlls/ntdll/sync.c:
- } while (InterlockedCompareExchange( u.l, new.l, old.l ) != old.l); + /* Someone else is also appending to the list, they have linked their + * node to `prev`, but hasn't changed lock->Ptr yet. So we wait for + * the lock to change and retry. */ + RtlWaitOnAddress(&lock->Ptr, &expected.Ptr, sizeof(expected.Ptr), + NULL); + return FALSE; + } + }
- if (!wait) return; - RtlWaitOnAddress( u.s, &new.s, sizeof(struct srw_lock), NULL ); + /* Once we reach here, `prev->next` can't be changed by anyone but us. So + * if we fail to change lock->Ptr, we have to reset it so others can append + * to the list. */ + new = srwlock_from_waiter(&waiter, tag); But this can't be possible, can it? Only the thread that successfully updated prev->next (i.e. this thread) can reach here. So that should just be assert(!prev), or am I missing something?
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/3504#note_43114