Skip to content

Commit 6a55eb1

Browse files
committed
Merge pull request #1934 from benpeart/fscache-thread-safe-enable-gfw
fscache: make fscache_enable() thread safe
2 parents 953918c + 7419cbf commit 6a55eb1

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
@@ -11,6 +11,7 @@
1111
#include "dir.h"
1212
#define SECURITY_WIN32
1313
#include <sspi.h>
14+
#include "win32/fscache.h"
1415

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

@@ -3296,6 +3297,9 @@ int wmain(int argc, const wchar_t **wargv)
32963297
/* initialize critical section for waitpid pinfo_t list */
32973298
InitializeCriticalSection(&pinfo_cs);
32983299

3300+
/* initialize critical section for fscache */
3301+
InitializeCriticalSection(&fscache_cs);
3302+
32993303
/* set up default file mode and file modes for stdin/out/err */
33003304
_fmode = _O_BINARY;
33013305
_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.
@@ -385,12 +385,12 @@ int fscache_enable(size_t initial_size)
385385
* opendir and lstat function pointers are redirected if
386386
* any threads are using the fscache.
387387
*/
388+
EnterCriticalSection(&fscache_cs);
388389
if (!initialized) {
389-
InitializeCriticalSection(&mutex);
390390
if (!dwTlsIndex) {
391391
dwTlsIndex = TlsAlloc();
392392
if (dwTlsIndex == TLS_OUT_OF_INDEXES) {
393-
LeaveCriticalSection(&mutex);
393+
LeaveCriticalSection(&fscache_cs);
394394
return 0;
395395
}
396396
}
@@ -399,12 +399,13 @@ int fscache_enable(size_t initial_size)
399399
opendir = fscache_opendir;
400400
lstat = fscache_lstat;
401401
}
402-
InterlockedIncrement(&initialized);
402+
initialized++;
403+
LeaveCriticalSection(&fscache_cs);
403404

404405
/* refcount the thread specific initialization */
405406
cache = fscache_getcache();
406407
if (cache) {
407-
InterlockedIncrement(&cache->enabled);
408+
cache->enabled++;
408409
} else {
409410
cache = (struct fscache *)xcalloc(1, sizeof(*cache));
410411
cache->enabled = 1;
@@ -438,7 +439,7 @@ void fscache_disable(void)
438439
BUG("fscache_disable() called on a thread where fscache has not been initialized");
439440
if (!cache->enabled)
440441
BUG("fscache_disable() called on an fscache that is already disabled");
441-
InterlockedDecrement(&cache->enabled);
442+
cache->enabled--;
442443
if (!cache->enabled) {
443444
TlsSetValue(dwTlsIndex, NULL);
444445
trace_printf_key(&trace_fscache, "fscache_disable: lstat %u, opendir %u, "
@@ -451,12 +452,14 @@ void fscache_disable(void)
451452
}
452453

453454
/* update the global fscache initialization */
454-
InterlockedDecrement(&initialized);
455+
EnterCriticalSection(&fscache_cs);
456+
initialized--;
455457
if (!initialized) {
456458
/* reset opendir and lstat to the original implementations */
457459
opendir = dirent_opendir;
458460
lstat = mingw_lstat;
459461
}
462+
LeaveCriticalSection(&fscache_cs);
460463

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

630633
hashmap_iter_init(&cache->map, &iter);
631634
while ((e = hashmap_iter_next(&iter)))
@@ -637,9 +640,9 @@ void fscache_merge(struct fscache *dest)
637640
dest->opendir_requests += cache->opendir_requests;
638641
dest->fscache_requests += cache->fscache_requests;
639642
dest->fscache_misses += cache->fscache_misses;
640-
LeaveCriticalSection(&mutex);
643+
initialized--;
644+
LeaveCriticalSection(&fscache_cs);
641645

642646
free(cache);
643647

644-
InterlockedDecrement(&initialized);
645648
}

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)