From c4141bc11c3d86d41a28da6418bb36a8f9668035 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Wed, 27 Apr 2022 09:39:24 -0400
Subject: [PATCH] log: Wrap the call to the logging implementation in a mutex.
Fixes #2463.
---
src/SDL.c | 8 +++++++-
src/SDL_log.c | 25 +++++++++++++++++++++++++
2 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/src/SDL.c b/src/SDL.c
index 68a4f5da2c0..08fed1ea4d9 100644
--- a/src/SDL.c
+++ b/src/SDL.c
@@ -147,6 +147,9 @@ SDL_SetMainReady(void)
SDL_MainIsReady = SDL_TRUE;
}
+void SDL_LogInit(void);
+void SDL_LogQuit(void);
+
int
SDL_InitSubSystem(Uint32 flags)
{
@@ -156,6 +159,8 @@ SDL_InitSubSystem(Uint32 flags)
return SDL_SetError("Application didn't initialize properly, did you include SDL_main.h in the file containing your main() function?");
}
+ SDL_LogInit();
+
/* Clear the error message */
SDL_ClearError();
@@ -470,12 +475,13 @@ SDL_Quit(void)
SDL_ClearHints();
SDL_AssertionsQuit();
- SDL_LogResetPriorities();
#if SDL_USE_LIBDBUS
SDL_DBus_Quit();
#endif
+ SDL_LogQuit();
+
/* Now that every subsystem has been quit, we reset the subsystem refcount
* and the list of initialized subsystems.
*/
diff --git a/src/SDL_log.c b/src/SDL_log.c
index dfbaca499d3..b31574da994 100644
--- a/src/SDL_log.c
+++ b/src/SDL_log.c
@@ -28,6 +28,7 @@
#include "SDL_error.h"
#include "SDL_log.h"
+#include "SDL_mutex.h"
#if HAVE_STDIO_H
#include <stdio.h>
@@ -59,6 +60,7 @@ static SDL_LogPriority SDL_application_priority = DEFAULT_APPLICATION_PRIORITY;
static SDL_LogPriority SDL_test_priority = DEFAULT_TEST_PRIORITY;
static SDL_LogOutputFunction SDL_log_function = SDL_LogOutput;
static void *SDL_log_userdata = NULL;
+static SDL_mutex *log_function_mutex = NULL;
static const char *SDL_priority_prefixes[SDL_NUM_LOG_PRIORITIES] = {
NULL,
@@ -92,6 +94,24 @@ static int SDL_android_priority[SDL_NUM_LOG_PRIORITIES] = {
};
#endif /* __ANDROID__ */
+void
+SDL_LogInit(void)
+{
+ if (!log_function_mutex) {
+ /* if this fails we'll try to continue without it. */
+ log_function_mutex = SDL_CreateMutex();
+ }
+}
+
+void
+SDL_LogQuit(void)
+{
+ SDL_LogResetPriorities();
+ if (log_function_mutex) {
+ SDL_DestroyMutex(log_function_mutex);
+ log_function_mutex = NULL;
+ }
+}
void
SDL_LogSetAllPriority(SDL_LogPriority priority)
@@ -298,7 +318,12 @@ SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list
}
}
+ /* this mutex creation can race if you log from two threads at startup. You should have called SDL_Init first! */
+ if (!log_function_mutex) { log_function_mutex = SDL_CreateMutex(); }
+ if (log_function_mutex) { SDL_LockMutex(log_function_mutex); }
SDL_log_function(SDL_log_userdata, category, priority, message);
+ if (log_function_mutex) { SDL_UnlockMutex(log_function_mutex); }
+
SDL_free(message);
}