log: Wrap the call to the logging implementation in a mutex. Fixes #2463.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
diff --git a/src/SDL.c b/src/SDL.c
index 68a4f5d..08fed1e 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 dfbaca4..b31574d 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);
}