Zhiyi Zhang (@zhiyi) commented about dlls/rtworkq/queue.c:
key >>= 32; + IUnknown_AddRef(&item->IUnknown_iface); if ((key & WAIT_ITEM_KEY_MASK) == WAIT_ITEM_KEY_MASK) { - IRtwqAsyncResult_SetStatus(item->result, RTWQ_E_OPERATION_CANCELLED); - invoke_async_callback(item->result); - CloseThreadpoolWait(item->u.wait_object); + wait_object = item->u.wait_object; item->u.wait_object = NULL; + LeaveCriticalSection(&queue->cs); + + SetThreadpoolWait(wait_object, NULL, NULL); + WaitForThreadpoolWaitCallbacks(wait_object, TRUE); + CloseThreadpoolWait(wait_object); + + EnterCriticalSection(&queue->cs);
I don't think you need to re-enter queue->cs? You should restructure it a bit. When the item is found, we break out of the loop and won't need to access queue->pending_items anymore. queue_release_pending_item() has its own Enter/LeaveCriticalSection(). -- https://gitlab.winehq.org/wine/wine/-/merge_requests/4243#note_63804