Commit e873d6098186f7733e5dd157d9c529f8b0b6f6d4

pionere 2022-11-07T10:02:06

fix handling of SDL_EventQ.active - SDL_EventQ.active is a bool variable -> do not use SDL_AtomicGet/Set, it does not help in any way - protect SDL_EventQ.active with SDL_EventQ.lock - set SDL_EventQ.active to FALSE by default

diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c
index 00a4053..52b72cd 100644
--- a/src/events/SDL_events.c
+++ b/src/events/SDL_events.c
@@ -86,7 +86,7 @@ typedef struct _SDL_SysWMEntry
 static struct
 {
     SDL_mutex *lock;
-    SDL_atomic_t active;
+    SDL_bool active;
     SDL_atomic_t count;
     int max_events_seen;
     SDL_EventEntry *head;
@@ -94,7 +94,7 @@ static struct
     SDL_EventEntry *free;
     SDL_SysWMEntry *wmmsg_used;
     SDL_SysWMEntry *wmmsg_free;
-} SDL_EventQ = { NULL, { 1 }, { 0 }, 0, NULL, NULL, NULL, NULL, NULL };
+} SDL_EventQ = { NULL, SDL_FALSE, { 0 }, 0, NULL, NULL, NULL, NULL, NULL };
 
 
 #if !SDL_JOYSTICK_DISABLED
@@ -474,7 +474,7 @@ SDL_StopEventLoop(void)
         SDL_LockMutex(SDL_EventQ.lock);
     }
 
-    SDL_AtomicSet(&SDL_EventQ.active, 0);
+    SDL_EventQ.active = SDL_FALSE;
 
     if (report && SDL_atoi(report)) {
         SDL_Log("SDL EVENT QUEUE: Maximum events in-flight: %d\n",
@@ -554,10 +554,12 @@ SDL_StartEventLoop(void)
             return -1;
         }
     }
+    SDL_LockMutex(SDL_EventQ.lock);
 
     if (!SDL_event_watchers_lock) {
         SDL_event_watchers_lock = SDL_CreateMutex();
         if (SDL_event_watchers_lock == NULL) {
+            SDL_UnlockMutex(SDL_EventQ.lock);
             return -1;
         }
     }
@@ -572,8 +574,10 @@ SDL_StartEventLoop(void)
     SDL_EventState(SDL_DROPTEXT, SDL_DISABLE);
 #endif
 
-    SDL_AtomicSet(&SDL_EventQ.active, 1);
-
+    SDL_EventQ.active = SDL_TRUE;
+    if (SDL_EventQ.lock) {
+        SDL_UnlockMutex(SDL_EventQ.lock);
+    }
     return 0;
 }
 
@@ -692,17 +696,20 @@ SDL_PeepEventsInternal(SDL_Event * events, int numevents, SDL_eventaction action
 {
     int i, used, sentinels_expected = 0;
 
-    /* Don't look after we've quit */
-    if (!SDL_AtomicGet(&SDL_EventQ.active)) {
-        /* We get a few spurious events at shutdown, so don't warn then */
-        if (action == SDL_GETEVENT) {
-            SDL_SetError("The event system has been shut down");
-        }
-        return (-1);
-    }
     /* Lock the event queue */
     used = 0;
     if (!SDL_EventQ.lock || SDL_LockMutex(SDL_EventQ.lock) == 0) {
+        /* Don't look after we've quit */
+        if (!SDL_EventQ.active) {
+            if (SDL_EventQ.lock) {
+                SDL_UnlockMutex(SDL_EventQ.lock);
+            }
+            /* We get a few spurious events at shutdown, so don't warn then */
+            if (action == SDL_GETEVENT) {
+                SDL_SetError("The event system has been shut down");
+            }
+            return (-1);
+        }
         if (action == SDL_ADDEVENT) {
             for (i = 0; i < numevents; ++i) {
                 used += SDL_AddEvent(&events[i]);
@@ -810,15 +817,12 @@ SDL_FlushEvent(Uint32 type)
 void
 SDL_FlushEvents(Uint32 minType, Uint32 maxType)
 {
+    SDL_EventEntry *entry, *next;
+    Uint32 type;
     /* !!! FIXME: we need to manually SDL_free() the strings in TEXTINPUT and
        drag'n'drop events if we're flushing them without passing them to the
        app, but I don't know if this is the right place to do that. */
 
-    /* Don't look after we've quit */
-    if (!SDL_AtomicGet(&SDL_EventQ.active)) {
-        return;
-    }
-
     /* Make sure the events are current */
 #if 0
     /* Actually, we can't do this since we might be flushing while processing
@@ -829,8 +833,13 @@ SDL_FlushEvents(Uint32 minType, Uint32 maxType)
 
     /* Lock the event queue */
     if (!SDL_EventQ.lock || SDL_LockMutex(SDL_EventQ.lock) == 0) {
-        SDL_EventEntry *entry, *next;
-        Uint32 type;
+        /* Don't look after we've quit */
+        if (!SDL_EventQ.active) {
+            if (SDL_EventQ.lock) {
+                SDL_UnlockMutex(SDL_EventQ.lock);
+            }
+            return;
+        }
         for (entry = SDL_EventQ.head; entry; entry = next) {
             next = entry->next;
             type = entry->event.type;