Skip to content

Commit 29f6866

Browse files
dschoGit for Windows Build Agent
authored andcommitted
Merge pull request #1934 from benpeart/fscache-thread-safe-enable-gfw
fscache: make fscache_enable() thread safe
2 parents 3855eee + e83cf15 commit 29f6866

File tree

3 files changed

+19
-10
lines changed

3 files changed

+19
-10
lines changed

compat/mingw.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "win32/lazyload.h"
99
#include "../config.h"
1010
#include "dir.h"
11+
#include "win32/fscache.h"
1112

1213
#define HCAST(type, handle) ((type)(intptr_t)handle)
1314

@@ -2674,6 +2675,9 @@ int wmain(int argc, const wchar_t **wargv)
26742675
/* initialize critical section for waitpid pinfo_t list */
26752676
InitializeCriticalSection(&pinfo_cs);
26762677

2678+
/* initialize critical section for fscache */
2679+
InitializeCriticalSection(&fscache_cs);
2680+
26772681
/* set up default file mode and file modes for stdin/out/err */
26782682
_fmode = _O_BINARY;
26792683
_setmode(_fileno(stdin), _O_BINARY);

compat/win32/fscache.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
static volatile long initialized;
99
static DWORD dwTlsIndex;
10-
static CRITICAL_SECTION mutex;
10+
CRITICAL_SECTION fscache_cs;
1111

1212
/*
1313
* Store one fscache per thread to avoid thread contention and locking.
@@ -368,12 +368,12 @@ int fscache_enable(size_t initial_size)
368368
* opendir and lstat function pointers are redirected if
369369
* any threads are using the fscache.
370370
*/
371+
EnterCriticalSection(&fscache_cs);
371372
if (!initialized) {
372-
InitializeCriticalSection(&mutex);
373373
if (!dwTlsIndex) {
374374
dwTlsIndex = TlsAlloc();
375375
if (dwTlsIndex == TLS_OUT_OF_INDEXES) {
376-
LeaveCriticalSection(&mutex);
376+
LeaveCriticalSection(&fscache_cs);
377377
return 0;
378378
}
379379
}
@@ -382,12 +382,13 @@ int fscache_enable(size_t initial_size)
382382
opendir = fscache_opendir;
383383
lstat = fscache_lstat;
384384
}
385-
InterlockedIncrement(&initialized);
385+
initialized++;
386+
LeaveCriticalSection(&fscache_cs);
386387

387388
/* refcount the thread specific initialization */
388389
cache = fscache_getcache();
389390
if (cache) {
390-
InterlockedIncrement(&cache->enabled);
391+
cache->enabled++;
391392
} else {
392393
cache = (struct fscache *)xcalloc(1, sizeof(*cache));
393394
cache->enabled = 1;
@@ -421,7 +422,7 @@ void fscache_disable(void)
421422
BUG("fscache_disable() called on a thread where fscache has not been initialized");
422423
if (!cache->enabled)
423424
BUG("fscache_disable() called on an fscache that is already disabled");
424-
InterlockedDecrement(&cache->enabled);
425+
cache->enabled--;
425426
if (!cache->enabled) {
426427
TlsSetValue(dwTlsIndex, NULL);
427428
trace_printf_key(&trace_fscache, "fscache_disable: lstat %u, opendir %u, "
@@ -434,12 +435,14 @@ void fscache_disable(void)
434435
}
435436

436437
/* update the global fscache initialization */
437-
InterlockedDecrement(&initialized);
438+
EnterCriticalSection(&fscache_cs);
439+
initialized--;
438440
if (!initialized) {
439441
/* reset opendir and lstat to the original implementations */
440442
opendir = dirent_opendir;
441443
lstat = mingw_lstat;
442444
}
445+
LeaveCriticalSection(&fscache_cs);
443446

444447
trace_printf_key(&trace_fscache, "fscache: disable\n");
445448
return;
@@ -605,7 +608,7 @@ void fscache_merge(struct fscache *dest)
605608
* isn't being used so the critical section only needs to prevent
606609
* the the child threads from stomping on each other.
607610
*/
608-
EnterCriticalSection(&mutex);
611+
EnterCriticalSection(&fscache_cs);
609612

610613
hashmap_iter_init(&cache->map, &iter);
611614
while ((e = hashmap_iter_next(&iter)))
@@ -617,9 +620,9 @@ void fscache_merge(struct fscache *dest)
617620
dest->opendir_requests += cache->opendir_requests;
618621
dest->fscache_requests += cache->fscache_requests;
619622
dest->fscache_misses += cache->fscache_misses;
620-
LeaveCriticalSection(&mutex);
623+
initialized--;
624+
LeaveCriticalSection(&fscache_cs);
621625

622626
free(cache);
623627

624-
InterlockedDecrement(&initialized);
625628
}

compat/win32/fscache.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
* for each thread where caching is desired.
77
*/
88

9+
extern CRITICAL_SECTION fscache_cs;
10+
911
int fscache_enable(size_t initial_size);
1012
#define enable_fscache(initial_size) fscache_enable(initial_size)
1113

0 commit comments

Comments
 (0)