Commit a8527429dc48ce0f9b63789715ed8eaa9b1abf0d

Edward Thomson 2012-11-13T14:48:10

unload dll / destroy hash ctxs at shutdown

diff --git a/src/global.c b/src/global.c
index de7e42d..d085089 100644
--- a/src/global.c
+++ b/src/global.c
@@ -79,6 +79,9 @@ void git_threads_shutdown(void)
 	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_global_st *git__global_state(void)
@@ -131,6 +134,9 @@ void git_threads_shutdown(void)
 {
 	pthread_key_delete(_tls_key);
 	_tls_init = 0;
+
+	/* Shut down any subsystems that have global state */
+	git_hash_global_shutdown();
 }
 
 git_global_st *git__global_state(void)
diff --git a/src/global.h b/src/global.h
index 1025cf7..b117714 100644
--- a/src/global.h
+++ b/src/global.h
@@ -14,6 +14,8 @@
 # define GIT_MEMORY_BARRIER MemoryBarrier()
 #elif defined(GIT_THREADS)
 # define GIT_MEMORY_BARRIER __sync_synchronize()
+#else
+# define GIT_MEMORY_BARRIER /* noop */
 #endif
 
 typedef struct {
diff --git a/src/hash.h b/src/hash.h
index 0e543ed..127be28 100644
--- a/src/hash.h
+++ b/src/hash.h
@@ -13,6 +13,7 @@ typedef struct git_hash_prov git_hash_prov;
 typedef struct git_hash_ctx git_hash_ctx;
 
 int git_hash_global_init(void);
+void git_hash_global_shutdown(void);
 
 int git_hash_ctx_init(git_hash_ctx *ctx);
 void git_hash_ctx_cleanup(git_hash_ctx *ctx);
diff --git a/src/hash/hash_generic.h b/src/hash/hash_generic.h
index 92c9cb9..7c4be78 100644
--- a/src/hash/hash_generic.h
+++ b/src/hash/hash_generic.h
@@ -17,6 +17,7 @@ struct git_hash_ctx {
 };
 
 #define git_hash_global_init() 0
+#define git_hash_global_shutdown() /* noop */
 #define git_hash_ctx_init(ctx) git_hash_init(ctx)
 #define git_hash_ctx_cleanup(ctx)
 
diff --git a/src/hash/hash_openssl.h b/src/hash/hash_openssl.h
index 39c47ae..3ae49a7 100644
--- a/src/hash/hash_openssl.h
+++ b/src/hash/hash_openssl.h
@@ -17,6 +17,7 @@ struct git_hash_ctx {
 };
 
 #define git_hash_global_init() 0
+#define git_hash_global_shutdown() /* noop */
 #define git_hash_ctx_init(ctx) git_hash_init(ctx)
 #define git_hash_ctx_cleanup(ctx)
 
diff --git a/src/hash/hash_ppc.h b/src/hash/hash_ppc.h
index df6570e..935f73f 100644
--- a/src/hash/hash_ppc.h
+++ b/src/hash/hash_ppc.h
@@ -21,6 +21,7 @@ struct git_hash_ctx {
 };
 
 #define git_hash_global_init() 0
+#define git_hash_global_shutdown() /* noop */
 #define git_hash_ctx_init(ctx) git_hash_init(ctx)
 #define git_hash_ctx_cleanup(ctx)
 
diff --git a/src/hash/hash_win32.c b/src/hash/hash_win32.c
index c490942..a89dffa 100644
--- a/src/hash/hash_win32.c
+++ b/src/hash/hash_win32.c
@@ -26,6 +26,8 @@ GIT_INLINE(int) hash_cng_prov_init(void)
 	char dll_path[MAX_PATH];
 	DWORD dll_path_len, size_len;
 
+	return -1;
+
 	/* Only use CNG on Windows 2008 / Vista SP1  or better (Windows 6.0 SP1) */
 	version_test.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
 	version_test.dwMajorVersion = 6;
@@ -79,6 +81,14 @@ GIT_INLINE(int) hash_cng_prov_init(void)
 	return 0;
 }
 
+GIT_INLINE(void) hash_cng_prov_shutdown(void)
+{
+	hash_prov.prov.cng.close_algorithm_provider(hash_prov.prov.cng.handle, 0);
+	FreeLibrary(hash_prov.prov.cng.dll);
+
+	hash_prov.type = INVALID;
+}
+
 /* Initialize CryptoAPI */
 GIT_INLINE(int) hash_cryptoapi_prov_init()
 {
@@ -89,6 +99,13 @@ GIT_INLINE(int) hash_cryptoapi_prov_init()
 	return 0;
 }
 
+GIT_INLINE(void) hash_cryptoapi_prov_shutdown(void)
+{
+	CryptReleaseContext(hash_prov.prov.cryptoapi.handle, 0);
+
+	hash_prov.type = INVALID;
+}
+
 int git_hash_global_init()
 {
 	int error = 0;
@@ -102,6 +119,14 @@ int git_hash_global_init()
 	return error;	
 }
 
+void git_hash_global_shutdown()
+{
+	if (hash_prov.type == CNG)
+		hash_cng_prov_shutdown();
+	else if(hash_prov.type == CRYPTOAPI)
+		hash_cryptoapi_prov_shutdown();
+}
+
 /* CryptoAPI: available in Windows XP and newer */
 
 GIT_INLINE(int) hash_ctx_cryptoapi_init(git_hash_ctx *ctx)