Skip to content

Commit 0c8a50b

Browse files
committed
Merge pull request git-for-windows#1934 from benpeart/fscache-thread-safe-enable-gfw
fscache: make fscache_enable() thread safe
2 parents 9e26270 + ee4b304 commit 0c8a50b

File tree

3 files changed

+18
-9
lines changed

3 files changed

+18
-9
lines changed

compat/mingw.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "../config.h"
1212
#include "../attr.h"
1313
#include "../string-list.h"
14+
#include "win32/fscache.h"
1415

1516
#define HCAST(type, handle) ((type)(intptr_t)handle)
1617

@@ -3190,6 +3191,9 @@ int wmain(int argc, const wchar_t **wargv)
31903191
InitializeCriticalSection(&pinfo_cs);
31913192
InitializeCriticalSection(&phantom_symlinks_cs);
31923193

3194+
/* initialize critical section for fscache */
3195+
InitializeCriticalSection(&fscache_cs);
3196+
31933197
/* set up default file mode and file modes for stdin/out/err */
31943198
_fmode = _O_BINARY;
31953199
_setmode(_fileno(stdin), _O_BINARY);

compat/win32/fscache.c

Lines changed: 12 additions & 9 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.
@@ -392,8 +392,8 @@ int fscache_enable(size_t initial_size)
392392
* opendir and lstat function pointers are redirected if
393393
* any threads are using the fscache.
394394
*/
395+
EnterCriticalSection(&fscache_cs);
395396
if (!initialized) {
396-
InitializeCriticalSection(&mutex);
397397
if (!dwTlsIndex) {
398398
dwTlsIndex = TlsAlloc();
399399
if (dwTlsIndex == TLS_OUT_OF_INDEXES)
@@ -404,12 +404,13 @@ int fscache_enable(size_t initial_size)
404404
opendir = fscache_opendir;
405405
lstat = fscache_lstat;
406406
}
407-
InterlockedIncrement(&initialized);
407+
initialized++;
408+
LeaveCriticalSection(&fscache_cs);
408409

409410
/* refcount the thread specific initialization */
410411
cache = fscache_getcache();
411412
if (cache) {
412-
InterlockedIncrement(&cache->enabled);
413+
cache->enabled++;
413414
} else {
414415
cache = (struct fscache *)xcalloc(1, sizeof(*cache));
415416
cache->enabled = 1;
@@ -443,7 +444,7 @@ void fscache_disable(void)
443444
BUG("fscache_disable() called on a thread where fscache has not been initialized");
444445
if (!cache->enabled)
445446
BUG("fscache_disable() called on an fscache that is already disabled");
446-
InterlockedDecrement(&cache->enabled);
447+
cache->enabled--;
447448
if (!cache->enabled) {
448449
TlsSetValue(dwTlsIndex, NULL);
449450
trace_printf_key(&trace_fscache, "fscache_disable: lstat %u, opendir %u, "
@@ -456,12 +457,14 @@ void fscache_disable(void)
456457
}
457458

458459
/* update the global fscache initialization */
459-
InterlockedDecrement(&initialized);
460+
EnterCriticalSection(&fscache_cs);
461+
initialized--;
460462
if (!initialized) {
461463
/* reset opendir and lstat to the original implementations */
462464
opendir = dirent_opendir;
463465
lstat = mingw_lstat;
464466
}
467+
LeaveCriticalSection(&fscache_cs);
465468

466469
trace_printf_key(&trace_fscache, "fscache: disable\n");
467470
return;
@@ -628,7 +631,7 @@ void fscache_merge(struct fscache *dest)
628631
* isn't being used so the critical section only needs to prevent
629632
* the the child threads from stomping on each other.
630633
*/
631-
EnterCriticalSection(&mutex);
634+
EnterCriticalSection(&fscache_cs);
632635

633636
hashmap_iter_init(&cache->map, &iter);
634637
while ((e = hashmap_iter_next(&iter)))
@@ -640,9 +643,9 @@ void fscache_merge(struct fscache *dest)
640643
dest->opendir_requests += cache->opendir_requests;
641644
dest->fscache_requests += cache->fscache_requests;
642645
dest->fscache_misses += cache->fscache_misses;
643-
LeaveCriticalSection(&mutex);
646+
initialized--;
647+
LeaveCriticalSection(&fscache_cs);
644648

645649
free(cache);
646650

647-
InterlockedDecrement(&initialized);
648651
}

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)