From @iamahuman state machine description, it looks like asyncs use "wait" operation for different things depending on the nature of the async. Some use it to "close" the async https://gitlab.winehq.org/wine/wine/-/merge_requests/6369/diffs#9c0778468c57..., others to "signal completion" (sic) https://gitlab.winehq.org/wine/wine/-/merge_requests/6369/diffs#9c0778468c57.... Is this what the cancelling thread is supposed to do on behalf of the thread normally handling the async? Using "wait" for these seems quite misleading to me.
If I had to guess, it's probably to "save" wineserver round trips. It's also possible that, back then, the resulting complexity was not well thought out. I have a few ideas as to how to stop wine abusing waits, but I'm hesitant to proceed before a refactor.