summaryrefslogtreecommitdiff
path: root/src/win32/pthread.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/win32/pthread.c')
-rw-r--r--src/win32/pthread.c116
1 files changed, 113 insertions, 3 deletions
diff --git a/src/win32/pthread.c b/src/win32/pthread.c
index 2f263b3e0..db8927471 100644
--- a/src/win32/pthread.c
+++ b/src/win32/pthread.c
@@ -6,6 +6,7 @@
*/
#include "pthread.h"
+#include "../global.h"
int pthread_create(
pthread_t *GIT_RESTRICT thread,
@@ -127,9 +128,10 @@ int pthread_cond_signal(pthread_cond_t *cond)
return 0;
}
-/* pthread_cond_broadcast is not implemented because doing so with just Win32 events
- * is quite complicated, and no caller in libgit2 uses it yet. */
-
+/* pthread_cond_broadcast is not implemented because doing so with just
+ * Win32 events is quite complicated, and no caller in libgit2 uses it
+ * yet.
+ */
int pthread_num_processors_np(void)
{
DWORD_PTR p, s;
@@ -142,3 +144,111 @@ int pthread_num_processors_np(void)
return n ? n : 1;
}
+
+static HINSTANCE win32_kernel32_dll;
+
+typedef void (WINAPI *win32_srwlock_fn)(GIT_SRWLOCK *);
+
+static win32_srwlock_fn win32_srwlock_initialize;
+static win32_srwlock_fn win32_srwlock_acquire_shared;
+static win32_srwlock_fn win32_srwlock_release_shared;
+static win32_srwlock_fn win32_srwlock_acquire_exclusive;
+static win32_srwlock_fn win32_srwlock_release_exclusive;
+
+int pthread_rwlock_init(
+ pthread_rwlock_t *GIT_RESTRICT lock,
+ const pthread_rwlockattr_t *GIT_RESTRICT attr)
+{
+ (void)attr;
+
+ if (win32_srwlock_initialize)
+ win32_srwlock_initialize(&lock->native.srwl);
+ else
+ InitializeCriticalSection(&lock->native.csec);
+
+ return 0;
+}
+
+int pthread_rwlock_rdlock(pthread_rwlock_t *lock)
+{
+ if (win32_srwlock_acquire_shared)
+ win32_srwlock_acquire_shared(&lock->native.srwl);
+ else
+ EnterCriticalSection(&lock->native.csec);
+
+ return 0;
+}
+
+int pthread_rwlock_rdunlock(pthread_rwlock_t *lock)
+{
+ if (win32_srwlock_release_shared)
+ win32_srwlock_release_shared(&lock->native.srwl);
+ else
+ LeaveCriticalSection(&lock->native.csec);
+
+ return 0;
+}
+
+int pthread_rwlock_wrlock(pthread_rwlock_t *lock)
+{
+ if (win32_srwlock_acquire_exclusive)
+ win32_srwlock_acquire_exclusive(&lock->native.srwl);
+ else
+ EnterCriticalSection(&lock->native.csec);
+
+ return 0;
+}
+
+int pthread_rwlock_wrunlock(pthread_rwlock_t *lock)
+{
+ if (win32_srwlock_release_exclusive)
+ win32_srwlock_release_exclusive(&lock->native.srwl);
+ else
+ LeaveCriticalSection(&lock->native.csec);
+
+ return 0;
+}
+
+int pthread_rwlock_destroy(pthread_rwlock_t *lock)
+{
+ if (!win32_srwlock_initialize)
+ DeleteCriticalSection(&lock->native.csec);
+ git__memzero(lock, sizeof(*lock));
+ return 0;
+}
+
+
+static void win32_pthread_shutdown(void)
+{
+ if (win32_kernel32_dll) {
+ FreeLibrary(win32_kernel32_dll);
+ win32_kernel32_dll = NULL;
+ }
+}
+
+int win32_pthread_initialize(void)
+{
+ if (win32_kernel32_dll)
+ return 0;
+
+ win32_kernel32_dll = LoadLibrary("Kernel32.dll");
+ if (!win32_kernel32_dll) {
+ giterr_set(GITERR_OS, "Could not load Kernel32.dll!");
+ return -1;
+ }
+
+ win32_srwlock_initialize = (win32_srwlock_fn)
+ GetProcAddress(win32_kernel32_dll, "InitializeSRWLock");
+ win32_srwlock_acquire_shared = (win32_srwlock_fn)
+ GetProcAddress(win32_kernel32_dll, "AcquireSRWLockShared");
+ win32_srwlock_release_shared = (win32_srwlock_fn)
+ GetProcAddress(win32_kernel32_dll, "ReleaseSRWLockShared");
+ win32_srwlock_acquire_exclusive = (win32_srwlock_fn)
+ GetProcAddress(win32_kernel32_dll, "AcquireSRWLockExclusive");
+ win32_srwlock_release_exclusive = (win32_srwlock_fn)
+ GetProcAddress(win32_kernel32_dll, "ReleaseSRWLockExclusive");
+
+ git__on_shutdown(win32_pthread_shutdown);
+
+ return 0;
+}