summaryrefslogtreecommitdiff
path: root/src/netops.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/netops.c')
-rw-r--r--src/netops.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/netops.c b/src/netops.c
index 7bce159ad..ba1a329e0 100644
--- a/src/netops.c
+++ b/src/netops.c
@@ -35,6 +35,11 @@
#include "http_parser.h"
#include "global.h"
+#if defined(GIT_SSL) && defined(GIT_THREADS)
+/* OpenSSL wants us to keep an array of locks */
+static git_mutex *openssl_locks;
+#endif
+
#ifdef GIT_WIN32
static void net_set_error(const char *str)
{
@@ -387,6 +392,24 @@ cert_fail_name:
return -1;
}
+#ifdef GIT_THREADS
+void openssl_locking_function(int mode, int n, const char *file, int line)
+{
+ int lock;
+
+ GIT_UNUSED(file);
+ GIT_UNUSED(line);
+
+ lock = mode & CRYPTO_LOCK;
+
+ if (lock) {
+ git_mutex_lock(&openssl_locks[n]);
+ } else {
+ git_mutex_unlock(&openssl_locks[n]);
+ }
+}
+#endif
+
/**
* The OpenSSL init functions are not reentrant so we need to init
* them under lock.
@@ -409,6 +432,25 @@ static int init_ssl(void)
SSL_library_init();
SSL_load_error_strings();
+#ifdef GIT_THREADS
+ {
+ int num_locks, i;
+
+
+ CRYPTO_set_locking_callback(openssl_locking_function);
+
+ num_locks = CRYPTO_num_locks();
+ openssl_locks = git__calloc(num_locks, sizeof(git_mutex));
+ for (i = 0; i < num_locks; i++) {
+ if (git_mutex_init(&openssl_locks[i]) < 0) {
+ git_mutex_unlock(&git__ssl_mutex);
+ giterr_set(GITERR_SSL, "failed to init lock %d", i);
+ return -1;
+ }
+ }
+ }
+#endif
+
git_atomic_set(&git__ssl_init, 1);
git_mutex_unlock(&git__ssl_mutex);