I was debugging some code in FreeRDP that seems to sometimes have huge input delays and found out that SDL_WaitEventTimeout seems to be the culprit. I have something that's similar to this loop (from FreeRDP):
while (!sdl->shallAbort())
{
SDL_Event windowEvent = {};
while (!sdl->shallAbort() && SDL_WaitEventTimeout(nullptr, 1000))
{
...
}
}
It seems to happen when the cursor changes, specifically there seems to be a race condition in Wayland_CursorStateSetCursor.
- The main thread enters
Wayland_WaitEventTimeout, flushes, and blocks in poll on the display fd.
- A cursor change (e.g., from
SDL_SetCursor called from another thread, or from an SDL main-thread callback) queues Wayland requests in the write buffer.
- Neither
Wayland_ShowCursor() nor Wayland_CursorStateSetCursor calls wl_display_flush or Wayland_SendWakeupEvent.
- The cursor thread is also blocked with infinite timeout (
timeoutNS is -1 initially) on the same fd.
- The compositor never receives the cursor requests, so it sends no events and
poll never returns.
Probably the simplest thing to do would be to flush cursor events in Wayland_CursorStateSetCursor or alternatively to call Wayland_SendWakeupEvent to avoid a deadlock.
I was debugging some code in FreeRDP that seems to sometimes have huge input delays and found out that
SDL_WaitEventTimeoutseems to be the culprit. I have something that's similar to this loop (from FreeRDP):It seems to happen when the cursor changes, specifically there seems to be a race condition in
Wayland_CursorStateSetCursor.Wayland_WaitEventTimeout, flushes, and blocks inpollon the display fd.SDL_SetCursorcalled from another thread, or from an SDL main-thread callback) queues Wayland requests in the write buffer.Wayland_ShowCursor()norWayland_CursorStateSetCursorcallswl_display_flushorWayland_SendWakeupEvent.timeoutNSis -1 initially) on the same fd.pollnever returns.Probably the simplest thing to do would be to flush cursor events in
Wayland_CursorStateSetCursoror alternatively to callWayland_SendWakeupEventto avoid a deadlock.