I believe user handles have a generation that should guarantee against re-use.
Thanks for the pointer. I looked at the handle code and the generation takes up two bytes, which means that it will be recycled pretty soon (a freed handle index is immediately available for reuse with a new generation). In fact, I wrote a win32 program that ends up recycling a HWND value in less than 2 seconds under Wine, so I wouldn't want to rely on HWNDs being unique. In practice it would require either a misbehaving or malicious program and unfortunate timings to get into such a state in a way that affects the driver, but this doesn't really alleviate my concerns.
In any case, HWND recycling is only one of the concerns. The requirements for the alternatives are:
1. No double locking (between `pointer.mutex` and others) 2. Handle concurrent window destruction 3. Handle concurrent SetCursor 4. Take into account that we will likely need access to `wayland_surface` from within many of the pointer handlers anyway 5. Guard against HWND recycling (related to (2))
My current WIP best effort is at: https://gitlab.winehq.org/afrantzis/wine/-/commits/wayland-part-6-no-double-... (all changes are in last commit). Please let me know what you think.
My overall impression of trying to think through the various alternatives, is that avoiding double locking involves a lot of additional multi-threading synchronization complexity and assumptions. The complexity is high enough that although I tried hard to verify that the code is correct, I still don't feel 100% confident that I haven't missed some edge case, and that's not a good sign. The high complexity concern stands even if we decide to not care about (5) and just go for the rest (see for example the code in `pointer_handle_enter` in the `wayland-part-6-no-double-lock` branch).
It could be that I am missing something obvious, or a shift in perspective, or some additional assumptions, that would help produce a simpler and better alternative. Perhaps people like the current alternative branch better than the double locking anyway. However, at this time, I still find that the double locking approach is simpler to reason about than anything else I have come up with that tackles all of (2)-(5). Also, its failure mode is well known (i.e., deadlock) and "safe", compared to the uncharted territory of even more intricate thread synchronization, the possibility for inconsistent state and risk of user input reaching the wrong window.