On Windows platforms, we automatically clean up the thread-local storage upon detaching a thread via `DllMain()`. The thing is that this happens for every thread of applications that link against the libgit2 DLL, even those that don't have anything to do with libgit2 itself. As a result, we cannot assume that these unsuspecting threads make use of our `git_libgit2_init()` and `git_libgit2_shutdow()` reference counting, which may lead to racy situations: Thread 1 Thread 2 git_libgit2_shutdown() DllMain(DETACH_THREAD) git__free_tls_data() git_atomic_dec() == 0 git__free_tls_data() TlsFree(_tls_index) TlsGetValue(_tls_index) Due to the second thread never having executed `git_libgit2_init()`, the first thread will clean up TLS data and as a result also free the `_tls_index` variable. When detaching the second thread, we unconditionally access the now-free'd `_tls_index` variable, which is obviously not going to work out well. Fix the issue by converting the code to use fiber-local storage instead of thread-local storage. While FLS will behave the exact same as TLS if no fibers are in use, it does allow us to specify a destructor similar to the one that is accepted by pthread_key_create(3P). Like this, we do not have to manually free indices anymore, but will let the FLS handle calling the destructor. This allows us to get rid of `DllMain()` completely, as we only used it to keep track of when threads were exiting and results in an overall simplification of TLS cleanup.
Name |
Last commit
|
Last update |
---|---|---|
.. | ||
dir.c | Loading commit data... | |
dir.h | Loading commit data... | |
error.c | Loading commit data... | |
error.h | Loading commit data... | |
findfile.c | Loading commit data... | |
findfile.h | Loading commit data... | |
git2.rc | Loading commit data... | |
map.c | Loading commit data... | |
mingw-compat.h | Loading commit data... | |
msvc-compat.h | Loading commit data... | |
path_w32.c | Loading commit data... | |
path_w32.h | Loading commit data... | |
posix.h | Loading commit data... | |
posix_w32.c | Loading commit data... | |
precompiled.c | Loading commit data... | |
precompiled.h | Loading commit data... | |
reparse.h | Loading commit data... | |
thread.c | Loading commit data... | |
thread.h | Loading commit data... | |
utf-conv.c | Loading commit data... | |
utf-conv.h | Loading commit data... | |
version.h | Loading commit data... | |
w32_buffer.c | Loading commit data... | |
w32_buffer.h | Loading commit data... | |
w32_common.h | Loading commit data... | |
w32_crtdbg_stacktrace.c | Loading commit data... | |
w32_crtdbg_stacktrace.h | Loading commit data... | |
w32_stack.c | Loading commit data... | |
w32_stack.h | Loading commit data... | |
w32_util.c | Loading commit data... | |
w32_util.h | Loading commit data... | |
win32-compat.h | Loading commit data... |