On Mon Jan 30 17:16:06 2023 +0000, Alexandros Frantzis wrote:
Hi Ivan! The MsgWaitForMultipleObjectsEx **driver** function is expected to be called in two ways:
- data == NULL, count == 0
- data != NULL, count >= 1, with the handle at index `count - 1` being
the server queue handle. In the second case the server queue handle is appended internally by Wine and the count adjusted (see `win32u/message.c`). So, the `count - 1` value returned by the driver function ends up corresponding to `count` in the original user invocation (e.g., from (NtUser)MsgWaitForMultipleObjectsEx):
NtUserMsgWaitForMultipleObjectsEx(count = 2, pHandles = [h1, h2], ...) driver->pMsgWaitForMultipleObjectsEx(count' = 3, pHandles' = [h1, h2, server_queue_handle], ...) => 2, which is == count' - 1 => 2, which is == count (`WAIT_OBJECT_0 + nCount` as per the MSDN docs)
All of this to explain why the proposed change is not correct, since with this change (NtUser)MsgWaitForMultipleObjectsEx would end up returning the wrong value in this scenario (`WAIT_OBJECT_0 + nCount + 1` which is not, AFAIK, a meaningful value). Driver implementations (exception: Android, see below) have a separate code path for the `data == NULL` case which doesn't involve `process_events()`, and since if `data != NULL` all the Wine code paths give us `count >= 1`, I don't see how we can get into the situation you are trying to fix. Perhaps I am missing something, but are you sure this particular scenario is the reason for the failures you are seeing? FWIW, the Android driver doesn't seem to handle the `data == NULL, count == 0` scenario properly (i.e., it still calls ` if (process_events( mask )) return count - 1;`) but perhaps there is something else at play here which I am not familiar with. In any case, the Android driver is not relevant to your scenario.
Hello, I experienced occasional hits of the code path after `process_events()` with `count == 0` in the game I was trying to fix ( https://bugs.winehq.org/show_bug.cgi?id=54405 ). It resulted in `-1` from the driver function, without a mistake: I inserted a special check for it. What if I add a special case in `NtUserMsgWaitForMultipleObjectsEx` to clamp `nCount + 1` to `nCount` results instead of doing this in the driver functions?