util/dprintf.c: Make dprintf() thread safe

This commit is contained in:
Tau 2019-03-03 17:55:47 -05:00
parent 65d24c1ada
commit 39d1b89b1b
1 changed files with 27 additions and 5 deletions

View File

@ -9,6 +9,8 @@
#include "util/dprintf.h"
static long dbg_buf_lock_init;
static CRITICAL_SECTION dbg_buf_lock;
static char dbg_buf[16384];
static size_t dbg_buf_pos;
@ -23,6 +25,26 @@ void dprintf(const char *fmt, ...)
void dprintfv(const char *fmt, va_list ap)
{
long init;
/* Static constructors in C are difficult to do in a way that works under
both GCC and MSVC, so we have to use atomic ops to ensure that the
buffer mutex is correctly initialized instead. */
do {
init = InterlockedCompareExchange(&dbg_buf_lock_init, 0, 1);
if (init == 0) {
/* We won the init race, global variable is now set to 1, other
threads will spin until it becomes -1. */
InitializeCriticalSection(&dbg_buf_lock);
dbg_buf_lock_init = -1;
init = -1;
}
} while (init >= 0);
EnterCriticalSection(&dbg_buf_lock);
dbg_buf_pos += vsnprintf_s(
dbg_buf + dbg_buf_pos,
sizeof(dbg_buf) - dbg_buf_pos,
@ -34,13 +56,13 @@ void dprintfv(const char *fmt, va_list ap)
abort();
}
if (strchr(dbg_buf, '\n') == NULL) {
return;
if (strchr(dbg_buf, '\n') != NULL) {
OutputDebugStringA(dbg_buf);
dbg_buf_pos = 0;
dbg_buf[0] = '\0';
}
OutputDebugStringA(dbg_buf);
dbg_buf_pos = 0;
dbg_buf[0] = '\0';
LeaveCriticalSection(&dbg_buf_lock);
}
void dwprintf(const wchar_t *fmt, ...)