Browse Source

events: Only add sentinels for pumping done inside SDL_WaitEventTimeout()

We don't want to catch explicit SDL_PumpEvents() calls by the application with
our polling check to avoid stale data. If the call to SDL_PumpEvents() produced
no events, there will be a sentinel sitting in the queue that will cause
SDL_PollEvent() to immediately return 0 next time it is called.

Our SDL_WaitEventTimeout() implementation avoids this issue by always popping
an event after calling SDL_PumpEvents(). This will remove the new sentinel if
we didn't get any new events.
Cameron Gutman 3 years ago
parent
commit
e9134b045a
1 changed files with 11 additions and 5 deletions
  1. 11 5
      src/events/SDL_events.c

+ 11 - 5
src/events/SDL_events.c

@@ -809,7 +809,7 @@ SDL_FlushEvents(Uint32 minType, Uint32 maxType)
 
 
 /* Run the system dependent event loops */
 /* Run the system dependent event loops */
 void
 void
-SDL_PumpEvents(void)
+SDL_PumpEventsInternal(SDL_bool push_sentinel)
 {
 {
     SDL_VideoDevice *_this = SDL_GetVideoDevice();
     SDL_VideoDevice *_this = SDL_GetVideoDevice();
 
 
@@ -837,7 +837,7 @@ SDL_PumpEvents(void)
 
 
     SDL_SendPendingSignalEvents();  /* in case we had a signal handler fire, etc. */
     SDL_SendPendingSignalEvents();  /* in case we had a signal handler fire, etc. */
 
 
-    if (SDL_GetEventState(SDL_POLLSENTINEL) == SDL_ENABLE) {
+    if (push_sentinel && SDL_GetEventState(SDL_POLLSENTINEL) == SDL_ENABLE) {
         SDL_Event sentinel;
         SDL_Event sentinel;
 
 
         SDL_zero(sentinel);
         SDL_zero(sentinel);
@@ -846,6 +846,12 @@ SDL_PumpEvents(void)
     }
     }
 }
 }
 
 
+void
+SDL_PumpEvents()
+{
+    SDL_PumpEventsInternal(SDL_FALSE);
+}
+
 /* Public functions */
 /* Public functions */
 
 
 int
 int
@@ -885,7 +891,7 @@ SDL_WaitEventTimeout_Device(_THIS, SDL_Window *wakeup_window, SDL_Event * event,
            c) Periodic processing that takes place in some platform PumpEvents() functions happens
            c) Periodic processing that takes place in some platform PumpEvents() functions happens
            d) Signals received in WaitEventTimeout() are turned into SDL events
            d) Signals received in WaitEventTimeout() are turned into SDL events
         */
         */
-        SDL_PumpEvents();
+        SDL_PumpEventsInternal(SDL_TRUE);
 
 
         if (!_this->wakeup_lock || SDL_LockMutex(_this->wakeup_lock) == 0) {
         if (!_this->wakeup_lock || SDL_LockMutex(_this->wakeup_lock) == 0) {
             int status = SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT);
             int status = SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT);
@@ -984,7 +990,7 @@ SDL_WaitEventTimeout(SDL_Event * event, int timeout)
 
 
     /* If there isn't a poll sentinel event pending, pump events and add one */
     /* If there isn't a poll sentinel event pending, pump events and add one */
     if (SDL_AtomicGet(&SDL_sentinel_pending) == 0) {
     if (SDL_AtomicGet(&SDL_sentinel_pending) == 0) {
-        SDL_PumpEvents();
+        SDL_PumpEventsInternal(SDL_TRUE);
     }
     }
 
 
     /* First check for existing events */
     /* First check for existing events */
@@ -1031,7 +1037,7 @@ SDL_WaitEventTimeout(SDL_Event * event, int timeout)
     }
     }
 
 
     for (;;) {
     for (;;) {
-        SDL_PumpEvents();
+        SDL_PumpEventsInternal(SDL_TRUE);
         switch (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
         switch (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
         case -1:
         case -1:
             return 0;
             return 0;