mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-30 00:04:03 +00:00
move hash library func ptrs to global global
This commit is contained in:
parent
603bee0791
commit
7ebefd22e7
@ -27,8 +27,10 @@ GIT_BEGIN_DECL
|
|||||||
*
|
*
|
||||||
* If libgit2 has been built without GIT_THREADS
|
* If libgit2 has been built without GIT_THREADS
|
||||||
* support, this function is a no-op.
|
* support, this function is a no-op.
|
||||||
|
*
|
||||||
|
* @return 0 or an error code
|
||||||
*/
|
*/
|
||||||
GIT_EXTERN(void) git_threads_init(void);
|
GIT_EXTERN(int) git_threads_init(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shutdown the threading system.
|
* Shutdown the threading system.
|
||||||
|
45
src/global.c
45
src/global.c
@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
#include "hash.h"
|
||||||
#include "git2/threads.h"
|
#include "git2/threads.h"
|
||||||
#include "thread-utils.h"
|
#include "thread-utils.h"
|
||||||
|
|
||||||
@ -38,19 +39,39 @@ git_mutex git__mwindow_mutex;
|
|||||||
* functions are not available in that case.
|
* functions are not available in that case.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* `git_threads_init()` allows subsystems to perform global setup,
|
||||||
|
* which may take place in the global scope. An explicit memory
|
||||||
|
* fence exists at the exit of `git_threads_init()`. Without this,
|
||||||
|
* CPU cores are free to reorder cache invalidation of `_tls_init`
|
||||||
|
* before cache invalidation of the subsystems' newly written global
|
||||||
|
* state.
|
||||||
|
*/
|
||||||
#if defined(GIT_THREADS) && defined(GIT_WIN32)
|
#if defined(GIT_THREADS) && defined(GIT_WIN32)
|
||||||
|
|
||||||
static DWORD _tls_index;
|
static DWORD _tls_index;
|
||||||
static int _tls_init = 0;
|
static int _tls_init = 0;
|
||||||
|
|
||||||
void git_threads_init(void)
|
int git_threads_init(void)
|
||||||
{
|
{
|
||||||
|
int error;
|
||||||
|
|
||||||
if (_tls_init)
|
if (_tls_init)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
_tls_index = TlsAlloc();
|
_tls_index = TlsAlloc();
|
||||||
_tls_init = 1;
|
|
||||||
git_mutex_init(&git__mwindow_mutex);
|
git_mutex_init(&git__mwindow_mutex);
|
||||||
|
|
||||||
|
/* Initialize any other subsystems that have global state */
|
||||||
|
if ((error = git_hash_global_init()) >= 0)
|
||||||
|
_tls_init = 1;
|
||||||
|
|
||||||
|
if (error == 0)
|
||||||
|
_tls_init = 1;
|
||||||
|
|
||||||
|
GIT_MEMORY_BARRIER;
|
||||||
|
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void git_threads_shutdown(void)
|
void git_threads_shutdown(void)
|
||||||
@ -88,13 +109,22 @@ static void cb__free_status(void *st)
|
|||||||
git__free(st);
|
git__free(st);
|
||||||
}
|
}
|
||||||
|
|
||||||
void git_threads_init(void)
|
int git_threads_init(void)
|
||||||
{
|
{
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
if (_tls_init)
|
if (_tls_init)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
pthread_key_create(&_tls_key, &cb__free_status);
|
pthread_key_create(&_tls_key, &cb__free_status);
|
||||||
_tls_init = 1;
|
|
||||||
|
/* Initialize any other subsystems that have global state */
|
||||||
|
if ((error = git_hash_global_init()) >= 0)
|
||||||
|
_tls_init = 1;
|
||||||
|
|
||||||
|
GIT_MEMORY_BARRIER;
|
||||||
|
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void git_threads_shutdown(void)
|
void git_threads_shutdown(void)
|
||||||
@ -125,9 +155,10 @@ git_global_st *git__global_state(void)
|
|||||||
|
|
||||||
static git_global_st __state;
|
static git_global_st __state;
|
||||||
|
|
||||||
void git_threads_init(void)
|
int git_threads_init(void)
|
||||||
{
|
{
|
||||||
/* noop */
|
/* noop */
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void git_threads_shutdown(void)
|
void git_threads_shutdown(void)
|
||||||
|
11
src/global.h
11
src/global.h
@ -10,14 +10,15 @@
|
|||||||
#include "mwindow.h"
|
#include "mwindow.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
|
||||||
|
#if defined(GIT_THREADS) && defined(_MSC_VER)
|
||||||
|
# define GIT_MEMORY_BARRIER MemoryBarrier()
|
||||||
|
#elif defined(GIT_THREADS)
|
||||||
|
# define GIT_MEMORY_BARRIER __sync_synchronize()
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
git_error *last_error;
|
git_error *last_error;
|
||||||
git_error error_t;
|
git_error error_t;
|
||||||
|
|
||||||
#ifdef WIN32_SHA1
|
|
||||||
git_hash_prov hash_prov;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} git_global_st;
|
} git_global_st;
|
||||||
|
|
||||||
git_global_st *git__global_state(void);
|
git_global_st *git__global_state(void);
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
typedef struct git_hash_prov git_hash_prov;
|
typedef struct git_hash_prov git_hash_prov;
|
||||||
typedef struct git_hash_ctx git_hash_ctx;
|
typedef struct git_hash_ctx git_hash_ctx;
|
||||||
|
|
||||||
|
int git_hash_global_init(void);
|
||||||
|
|
||||||
int git_hash_ctx_init(git_hash_ctx *ctx);
|
int git_hash_ctx_init(git_hash_ctx *ctx);
|
||||||
void git_hash_ctx_cleanup(git_hash_ctx *ctx);
|
void git_hash_ctx_cleanup(git_hash_ctx *ctx);
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ struct git_hash_ctx {
|
|||||||
unsigned int W[16];
|
unsigned int W[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define git_hash_global_init() 0
|
||||||
#define git_hash_ctx_init(ctx) git_hash_init(ctx)
|
#define git_hash_ctx_init(ctx) git_hash_init(ctx)
|
||||||
#define git_hash_ctx_cleanup(ctx)
|
#define git_hash_ctx_cleanup(ctx)
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ struct git_hash_ctx {
|
|||||||
SHA_CTX c;
|
SHA_CTX c;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define git_hash_global_init() 0
|
||||||
#define git_hash_ctx_init(ctx) git_hash_init(ctx)
|
#define git_hash_ctx_init(ctx) git_hash_init(ctx)
|
||||||
#define git_hash_ctx_cleanup(ctx)
|
#define git_hash_ctx_cleanup(ctx)
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ struct git_hash_ctx {
|
|||||||
} buf;
|
} buf;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define git_hash_global_init() 0
|
||||||
#define git_hash_ctx_init(ctx) git_hash_init(ctx)
|
#define git_hash_ctx_init(ctx) git_hash_init(ctx)
|
||||||
#define git_hash_ctx_cleanup(ctx)
|
#define git_hash_ctx_cleanup(ctx)
|
||||||
|
|
||||||
|
@ -13,8 +13,12 @@
|
|||||||
#include <wincrypt.h>
|
#include <wincrypt.h>
|
||||||
#include <strsafe.h>
|
#include <strsafe.h>
|
||||||
|
|
||||||
|
static struct git_hash_prov hash_prov = {0};
|
||||||
|
|
||||||
|
/* Hash initialization */
|
||||||
|
|
||||||
/* Initialize CNG, if available */
|
/* Initialize CNG, if available */
|
||||||
GIT_INLINE(int) hash_cng_prov_init(git_hash_prov *prov)
|
GIT_INLINE(int) hash_cng_prov_init(void)
|
||||||
{
|
{
|
||||||
OSVERSIONINFOEX version_test = {0};
|
OSVERSIONINFOEX version_test = {0};
|
||||||
DWORD version_test_mask;
|
DWORD version_test_mask;
|
||||||
@ -43,67 +47,67 @@ GIT_INLINE(int) hash_cng_prov_init(git_hash_prov *prov)
|
|||||||
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, "\\") < 0 ||
|
||||||
StringCchCat(dll_path, MAX_PATH, GIT_HASH_CNG_DLL_NAME) < 0 ||
|
StringCchCat(dll_path, MAX_PATH, GIT_HASH_CNG_DLL_NAME) < 0 ||
|
||||||
(prov->prov.cng.dll = LoadLibrary(dll_path)) == NULL)
|
(hash_prov.prov.cng.dll = LoadLibrary(dll_path)) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Load the function addresses */
|
/* Load the function addresses */
|
||||||
if ((prov->prov.cng.open_algorithm_provider = (hash_win32_cng_open_algorithm_provider_fn)GetProcAddress(prov->prov.cng.dll, "BCryptOpenAlgorithmProvider")) == NULL ||
|
if ((hash_prov.prov.cng.open_algorithm_provider = (hash_win32_cng_open_algorithm_provider_fn)GetProcAddress(hash_prov.prov.cng.dll, "BCryptOpenAlgorithmProvider")) == NULL ||
|
||||||
(prov->prov.cng.get_property = (hash_win32_cng_get_property_fn)GetProcAddress(prov->prov.cng.dll, "BCryptGetProperty")) == NULL ||
|
(hash_prov.prov.cng.get_property = (hash_win32_cng_get_property_fn)GetProcAddress(hash_prov.prov.cng.dll, "BCryptGetProperty")) == NULL ||
|
||||||
(prov->prov.cng.create_hash = (hash_win32_cng_create_hash_fn)GetProcAddress(prov->prov.cng.dll, "BCryptCreateHash")) == NULL ||
|
(hash_prov.prov.cng.create_hash = (hash_win32_cng_create_hash_fn)GetProcAddress(hash_prov.prov.cng.dll, "BCryptCreateHash")) == NULL ||
|
||||||
(prov->prov.cng.finish_hash = (hash_win32_cng_finish_hash_fn)GetProcAddress(prov->prov.cng.dll, "BCryptFinishHash")) == NULL ||
|
(hash_prov.prov.cng.finish_hash = (hash_win32_cng_finish_hash_fn)GetProcAddress(hash_prov.prov.cng.dll, "BCryptFinishHash")) == NULL ||
|
||||||
(prov->prov.cng.hash_data = (hash_win32_cng_hash_data_fn)GetProcAddress(prov->prov.cng.dll, "BCryptHashData")) == NULL ||
|
(hash_prov.prov.cng.hash_data = (hash_win32_cng_hash_data_fn)GetProcAddress(hash_prov.prov.cng.dll, "BCryptHashData")) == NULL ||
|
||||||
(prov->prov.cng.destroy_hash = (hash_win32_cng_destroy_hash_fn)GetProcAddress(prov->prov.cng.dll, "BCryptDestroyHash")) == NULL ||
|
(hash_prov.prov.cng.destroy_hash = (hash_win32_cng_destroy_hash_fn)GetProcAddress(hash_prov.prov.cng.dll, "BCryptDestroyHash")) == NULL ||
|
||||||
(prov->prov.cng.close_algorithm_provider = (hash_win32_cng_close_algorithm_provider_fn)GetProcAddress(prov->prov.cng.dll, "BCryptCloseAlgorithmProvider")) == NULL) {
|
(hash_prov.prov.cng.close_algorithm_provider = (hash_win32_cng_close_algorithm_provider_fn)GetProcAddress(hash_prov.prov.cng.dll, "BCryptCloseAlgorithmProvider")) == NULL) {
|
||||||
FreeLibrary(prov->prov.cng.dll);
|
FreeLibrary(hash_prov.prov.cng.dll);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load the SHA1 algorithm */
|
/* Load the SHA1 algorithm */
|
||||||
if (prov->prov.cng.open_algorithm_provider(&prov->prov.cng.handle, GIT_HASH_CNG_HASH_TYPE, NULL, GIT_HASH_CNG_HASH_REUSABLE) < 0) {
|
if (hash_prov.prov.cng.open_algorithm_provider(&hash_prov.prov.cng.handle, GIT_HASH_CNG_HASH_TYPE, NULL, GIT_HASH_CNG_HASH_REUSABLE) < 0) {
|
||||||
FreeLibrary(prov->prov.cng.dll);
|
FreeLibrary(hash_prov.prov.cng.dll);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get storage space for the hash object */
|
/* Get storage space for the hash object */
|
||||||
if (prov->prov.cng.get_property(prov->prov.cng.handle, GIT_HASH_CNG_HASH_OBJECT_LEN, (PBYTE)&prov->prov.cng.hash_object_size, sizeof(DWORD), &size_len, 0) < 0) {
|
if (hash_prov.prov.cng.get_property(hash_prov.prov.cng.handle, GIT_HASH_CNG_HASH_OBJECT_LEN, (PBYTE)&hash_prov.prov.cng.hash_object_size, sizeof(DWORD), &size_len, 0) < 0) {
|
||||||
prov->prov.cng.close_algorithm_provider(prov->prov.cng.handle, 0);
|
hash_prov.prov.cng.close_algorithm_provider(hash_prov.prov.cng.handle, 0);
|
||||||
FreeLibrary(prov->prov.cng.dll);
|
FreeLibrary(hash_prov.prov.cng.dll);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
prov->type = CNG;
|
hash_prov.type = CNG;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize CryptoAPI */
|
/* Initialize CryptoAPI */
|
||||||
GIT_INLINE(int) hash_cryptoapi_prov_init(git_hash_prov *prov)
|
GIT_INLINE(int) hash_cryptoapi_prov_init()
|
||||||
{
|
{
|
||||||
if (!CryptAcquireContext(&prov->prov.cryptoapi.handle, NULL, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
|
if (!CryptAcquireContext(&hash_prov.prov.cryptoapi.handle, NULL, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
prov->type = CRYPTOAPI;
|
hash_prov.type = CRYPTOAPI;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hash_win32_prov_init(git_hash_prov *prov)
|
int git_hash_global_init()
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
assert(prov->type == INVALID);
|
if (hash_prov.type != INVALID)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* Try to load CNG */
|
if ((error = hash_cng_prov_init()) < 0)
|
||||||
if ((error = hash_cng_prov_init(prov)) < 0)
|
error = hash_cryptoapi_prov_init();
|
||||||
error = hash_cryptoapi_prov_init(prov);
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CryptoAPI: available in Windows XP and newer */
|
/* CryptoAPI: available in Windows XP and newer */
|
||||||
|
|
||||||
GIT_INLINE(int) hash_ctx_cryptoapi_init(git_hash_ctx *ctx, git_hash_prov *prov)
|
GIT_INLINE(int) hash_ctx_cryptoapi_init(git_hash_ctx *ctx)
|
||||||
{
|
{
|
||||||
ctx->type = CRYPTOAPI;
|
ctx->type = CRYPTOAPI;
|
||||||
ctx->prov = prov;
|
ctx->prov = &hash_prov;
|
||||||
|
|
||||||
return git_hash_init(ctx);
|
return git_hash_init(ctx);
|
||||||
}
|
}
|
||||||
@ -156,18 +160,18 @@ GIT_INLINE(void) hash_ctx_cryptoapi_cleanup(git_hash_ctx *ctx)
|
|||||||
|
|
||||||
/* CNG: Available in Windows Server 2008 and newer */
|
/* CNG: Available in Windows Server 2008 and newer */
|
||||||
|
|
||||||
GIT_INLINE(int) hash_ctx_cng_init(git_hash_ctx *ctx, git_hash_prov *prov)
|
GIT_INLINE(int) hash_ctx_cng_init(git_hash_ctx *ctx)
|
||||||
{
|
{
|
||||||
if ((ctx->ctx.cng.hash_object = git__malloc(prov->prov.cng.hash_object_size)) == NULL)
|
if ((ctx->ctx.cng.hash_object = git__malloc(hash_prov.prov.cng.hash_object_size)) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (prov->prov.cng.create_hash(prov->prov.cng.handle, &ctx->ctx.cng.hash_handle, ctx->ctx.cng.hash_object, prov->prov.cng.hash_object_size, NULL, 0, 0) < 0) {
|
if (hash_prov.prov.cng.create_hash(hash_prov.prov.cng.handle, &ctx->ctx.cng.hash_handle, ctx->ctx.cng.hash_object, hash_prov.prov.cng.hash_object_size, NULL, 0, 0) < 0) {
|
||||||
git__free(ctx->ctx.cng.hash_object);
|
git__free(ctx->ctx.cng.hash_object);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->type = CNG;
|
ctx->type = CNG;
|
||||||
ctx->prov = prov;
|
ctx->prov = &hash_prov;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -216,22 +220,21 @@ GIT_INLINE(void) hash_ctx_cng_cleanup(git_hash_ctx *ctx)
|
|||||||
|
|
||||||
int git_hash_ctx_init(git_hash_ctx *ctx)
|
int git_hash_ctx_init(git_hash_ctx *ctx)
|
||||||
{
|
{
|
||||||
git_global_st *global_state;
|
int error = 0;
|
||||||
git_hash_prov *hash_prov;
|
|
||||||
|
|
||||||
assert(ctx);
|
assert(ctx);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When compiled with GIT_THREADS, the global hash_prov data is
|
||||||
|
* initialized with git_threads_init. Otherwise, it must be initialized
|
||||||
|
* at first use.
|
||||||
|
*/
|
||||||
|
if (hash_prov.type == INVALID && (error = git_hash_global_init()) < 0)
|
||||||
|
return error;
|
||||||
|
|
||||||
memset(ctx, 0x0, sizeof(git_hash_ctx));
|
memset(ctx, 0x0, sizeof(git_hash_ctx));
|
||||||
|
|
||||||
if ((global_state = git__global_state()) == NULL)
|
return (hash_prov.type == CNG) ? hash_ctx_cng_init(ctx) : hash_ctx_cryptoapi_init(ctx);
|
||||||
return -1;
|
|
||||||
|
|
||||||
hash_prov = &global_state->hash_prov;
|
|
||||||
|
|
||||||
if (hash_prov->type == INVALID && hash_win32_prov_init(hash_prov) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return (hash_prov->type == CNG) ? hash_ctx_cng_init(ctx, hash_prov) : hash_ctx_cryptoapi_init(ctx, hash_prov);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int git_hash_init(git_hash_ctx *ctx)
|
int git_hash_init(git_hash_ctx *ctx)
|
||||||
|
Loading…
Reference in New Issue
Block a user