mirror of
https://git.proxmox.com/git/libgit2
synced 2025-06-18 21:35:20 +00:00
Load SRWLock APIs at runtime
This loads SRWLock APIs at runtime and in their absence (i.e. on Windows before Vista) falls back on a regular CRITICAL_SECTION that will not permit concurrent readers.
This commit is contained in:
parent
44d6553186
commit
430953417f
@ -287,13 +287,8 @@ FILE(GLOB SRC_H include/git2.h include/git2/*.h include/git2/sys/*.h)
|
||||
|
||||
# On Windows use specific platform sources
|
||||
IF (WIN32 AND NOT CYGWIN)
|
||||
ADD_DEFINITIONS(-DWIN32)
|
||||
ADD_DEFINITIONS(-DWIN32 -D_WIN32_WINNT=0x0501)
|
||||
FILE(GLOB SRC_OS src/win32/*.c src/win32/*.h)
|
||||
IF (THREADSAFE)
|
||||
ADD_DEFINITIONS(-D_WIN32_WINNT=0x0600)
|
||||
ELSE()
|
||||
ADD_DEFINITIONS(-D_WIN32_WINNT=0x0501)
|
||||
ENDIF()
|
||||
ELSEIF (AMIGA)
|
||||
ADD_DEFINITIONS(-DNO_ADDRINFO -DNO_READDIR_R)
|
||||
FILE(GLOB SRC_OS src/amiga/*.c src/amiga/*.h)
|
||||
|
12
src/global.c
12
src/global.c
@ -71,18 +71,22 @@ int git_threads_init(void)
|
||||
|
||||
GIT_MEMORY_BARRIER;
|
||||
|
||||
win32_pthread_initialize();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void git_threads_shutdown(void)
|
||||
{
|
||||
/* Shut down any subsystems that have global state */
|
||||
win32_pthread_shutdown();
|
||||
git_futils_dirs_free();
|
||||
git_hash_global_shutdown();
|
||||
|
||||
TlsFree(_tls_index);
|
||||
_tls_init = 0;
|
||||
git_mutex_free(&git__mwindow_mutex);
|
||||
|
||||
/* Shut down any subsystems that have global state */
|
||||
git_hash_global_shutdown();
|
||||
git_futils_dirs_free();
|
||||
git_mutex_free(&git__mwindow_mutex);
|
||||
}
|
||||
|
||||
git_global_st *git__global_state(void)
|
||||
|
@ -46,7 +46,8 @@ GIT_INLINE(int) hash_cng_prov_init(void)
|
||||
return -1;
|
||||
|
||||
/* Load bcrypt.dll explicitly from the system directory */
|
||||
if ((dll_path_len = GetSystemDirectory(dll_path, MAX_PATH)) == 0 || dll_path_len > MAX_PATH ||
|
||||
if ((dll_path_len = GetSystemDirectory(dll_path, MAX_PATH)) == 0 ||
|
||||
dll_path_len > MAX_PATH ||
|
||||
StringCchCat(dll_path, MAX_PATH, "\\") < 0 ||
|
||||
StringCchCat(dll_path, MAX_PATH, GIT_HASH_CNG_DLL_NAME) < 0 ||
|
||||
(hash_prov.prov.cng.dll = LoadLibrary(dll_path)) == NULL)
|
||||
|
@ -40,10 +40,6 @@ typedef git_atomic git_atomic_ssize;
|
||||
|
||||
#ifdef GIT_THREADS
|
||||
|
||||
#if defined(GIT_WIN32) && _WIN32_WINNT < 0x0600
|
||||
# error "Unsupported Windows version for thread support"
|
||||
#endif
|
||||
|
||||
#define git_thread pthread_t
|
||||
#define git_thread_create(thread, attr, start_routine, arg) \
|
||||
pthread_create(thread, attr, start_routine, arg)
|
||||
|
@ -127,9 +127,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,41 +143,111 @@ int pthread_num_processors_np(void)
|
||||
return n ? n : 1;
|
||||
}
|
||||
|
||||
|
||||
static HINSTANCE win32_kernel32_dll;
|
||||
|
||||
typedef void (WINAPI *win32_srwlock_fn)(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;
|
||||
InitializeSRWLock(lock);
|
||||
|
||||
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)
|
||||
{
|
||||
AcquireSRWLockShared(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)
|
||||
{
|
||||
ReleaseSRWLockShared(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)
|
||||
{
|
||||
AcquireSRWLockExclusive(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)
|
||||
{
|
||||
ReleaseSRWLockExclusive(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)
|
||||
{
|
||||
(void)lock;
|
||||
if (!win32_srwlock_initialize)
|
||||
DeleteCriticalSection(&lock->native.csec);
|
||||
git__memzero(lock, sizeof(*lock));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
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");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int win32_pthread_shutdown(void)
|
||||
{
|
||||
if (win32_kernel32_dll) {
|
||||
FreeLibrary(win32_kernel32_dll);
|
||||
win32_kernel32_dll = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -24,10 +24,17 @@ typedef int pthread_rwlockattr_t;
|
||||
typedef CRITICAL_SECTION pthread_mutex_t;
|
||||
typedef HANDLE pthread_t;
|
||||
typedef HANDLE pthread_cond_t;
|
||||
typedef SRWLOCK pthread_rwlock_t;
|
||||
|
||||
/* typedef struct { void *Ptr; } SRWLOCK; */
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
SRWLOCK srwl;
|
||||
CRITICAL_SECTION csec;
|
||||
} native;
|
||||
} pthread_rwlock_t;
|
||||
|
||||
#define PTHREAD_MUTEX_INITIALIZER {(void*)-1}
|
||||
#define PTHREAD_RWLOCK_INITIALIZER SRWLOCK_INIT
|
||||
|
||||
int pthread_create(
|
||||
pthread_t *GIT_RESTRICT thread,
|
||||
@ -61,4 +68,7 @@ int pthread_rwlock_wrlock(pthread_rwlock_t *);
|
||||
int pthread_rwlock_wrunlock(pthread_rwlock_t *);
|
||||
int pthread_rwlock_destroy(pthread_rwlock_t *);
|
||||
|
||||
extern int win32_pthread_initialize(void);
|
||||
extern int win32_pthread_shutdown(void);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user