mirror of
git://repo.or.cz/tinycc.git
synced 2026-06-17 15:44:18 +08:00
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:
parent
757507eb02
commit
6a7c3df4d5
11
tcc.h
11
tcc.h
@ -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) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user