win32: make compile lock initialization thread-safe

Use interlocked state transitions around the lazily initialized Windows
CRITICAL_SECTION so concurrent first-time callers cannot race into a
double initialization.
This commit is contained in:
Mounir IDRASSI 2026-05-15 18:49:26 +09:00
parent 757507eb02
commit 6a7c3df4d5

11
tcc.h
View File

@ -1918,10 +1918,15 @@ dwarf_read_sleb128(unsigned char **ln, unsigned char *end)
/********************************************************/ /********************************************************/
#if CONFIG_TCC_SEMLOCK #if CONFIG_TCC_SEMLOCK
#if defined _WIN32 #if defined _WIN32
typedef struct { int init; CRITICAL_SECTION cs; } TCCSem; typedef struct { volatile LONG init; CRITICAL_SECTION cs; } TCCSem;
static inline void wait_sem(TCCSem *p) { static inline void wait_sem(TCCSem *p) {
if (!p->init) if (InterlockedCompareExchange(&p->init, 1, 0) == 0) {
InitializeCriticalSection(&p->cs), p->init = 1; InitializeCriticalSection(&p->cs);
InterlockedExchange(&p->init, 2);
} else {
while (InterlockedCompareExchange(&p->init, 2, 2) != 2)
Sleep(0);
}
EnterCriticalSection(&p->cs); EnterCriticalSection(&p->cs);
} }
static inline void post_sem(TCCSem *p) { static inline void post_sem(TCCSem *p) {