Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fscache: make fscache_enable() thread safe #1934

Merged
merged 1 commit into from
Nov 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions compat/mingw.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "../config.h"
#include "../attr.h"
#include "../string-list.h"
#include "win32/fscache.h"

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

Expand Down Expand Up @@ -3182,6 +3183,9 @@ int wmain(int argc, const wchar_t **wargv)
InitializeCriticalSection(&pinfo_cs);
InitializeCriticalSection(&phantom_symlinks_cs);

/* initialize critical section for fscache */
InitializeCriticalSection(&fscache_cs);

/* set up default file mode and file modes for stdin/out/err */
_fmode = _O_BINARY;
_setmode(_fileno(stdin), _O_BINARY);
Expand Down
21 changes: 12 additions & 9 deletions compat/win32/fscache.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

static volatile long initialized;
static DWORD dwTlsIndex;
static CRITICAL_SECTION mutex;
CRITICAL_SECTION fscache_cs;

/*
* Store one fscache per thread to avoid thread contention and locking.
Expand Down Expand Up @@ -383,8 +383,8 @@ int fscache_enable(size_t initial_size)
* opendir and lstat function pointers are redirected if
* any threads are using the fscache.
*/
EnterCriticalSection(&fscache_cs);
if (!initialized) {
InitializeCriticalSection(&mutex);
if (!dwTlsIndex) {
dwTlsIndex = TlsAlloc();
if (dwTlsIndex == TLS_OUT_OF_INDEXES)
Expand All @@ -395,12 +395,13 @@ int fscache_enable(size_t initial_size)
opendir = fscache_opendir;
lstat = fscache_lstat;
}
InterlockedIncrement(&initialized);
initialized++;
LeaveCriticalSection(&fscache_cs);

/* refcount the thread specific initialization */
cache = fscache_getcache();
if (cache) {
InterlockedIncrement(&cache->enabled);
cache->enabled++;
} else {
cache = (struct fscache *)xcalloc(1, sizeof(*cache));
cache->enabled = 1;
Expand Down Expand Up @@ -434,7 +435,7 @@ void fscache_disable(void)
BUG("fscache_disable() called on a thread where fscache has not been initialized");
if (!cache->enabled)
BUG("fscache_disable() called on an fscache that is already disabled");
InterlockedDecrement(&cache->enabled);
cache->enabled--;
if (!cache->enabled) {
TlsSetValue(dwTlsIndex, NULL);
trace_printf_key(&trace_fscache, "fscache_disable: lstat %u, opendir %u, "
Expand All @@ -447,12 +448,14 @@ void fscache_disable(void)
}

/* update the global fscache initialization */
InterlockedDecrement(&initialized);
EnterCriticalSection(&fscache_cs);
initialized--;
if (!initialized) {
/* reset opendir and lstat to the original implementations */
opendir = dirent_opendir;
lstat = mingw_lstat;
}
LeaveCriticalSection(&fscache_cs);

trace_printf_key(&trace_fscache, "fscache: disable\n");
return;
Expand Down Expand Up @@ -619,7 +622,7 @@ void fscache_merge(struct fscache *dest)
* isn't being used so the critical section only needs to prevent
* the the child threads from stomping on each other.
*/
EnterCriticalSection(&mutex);
EnterCriticalSection(&fscache_cs);

hashmap_iter_init(&cache->map, &iter);
while ((e = hashmap_iter_next(&iter)))
Expand All @@ -631,9 +634,9 @@ void fscache_merge(struct fscache *dest)
dest->opendir_requests += cache->opendir_requests;
dest->fscache_requests += cache->fscache_requests;
dest->fscache_misses += cache->fscache_misses;
LeaveCriticalSection(&mutex);
initialized--;
LeaveCriticalSection(&fscache_cs);

free(cache);

InterlockedDecrement(&initialized);
}
2 changes: 2 additions & 0 deletions compat/win32/fscache.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
* for each thread where caching is desired.
*/

extern CRITICAL_SECTION fscache_cs;

int fscache_enable(size_t initial_size);
#define enable_fscache(initial_size) fscache_enable(initial_size)

Expand Down