diff -r 68e250ceb06e src/event/ngx_event_openssl.c
--- a/src/event/ngx_event_openssl.c	Tue Nov 19 15:25:24 2013 +0400
+++ b/src/event/ngx_event_openssl.c	Wed Dec 11 12:29:04 2013 -0500
@@ -8,6 +8,7 @@
 #include <ngx_config.h>
 #include <ngx_core.h>
 #include <ngx_event.h>
+#include <ngx_thread.h>
 
 
 typedef struct {
@@ -42,6 +43,17 @@
 static char *ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
 static void ngx_openssl_exit(ngx_cycle_t *cycle);
 
+#if (NGX_THREADS) && defined(OPENSSL_THREADS)
+static ngx_mutex_t* g_locks[CRYPTO_NUM_LOCKS] = {};
+
+static int ngx_install_openssl_locks(ngx_log_t *log);
+static int ngx_install_openssl_callbacks(ngx_log_t *log);
+static unsigned long ngx_openssl_thread_id(void);
+static void ngx_openssl_lock_fn(int mode, int idx, const char* file, int line);
+static int ngx_remove_openssl_callbacks(void);
+static int ngx_remove_openssl_locks(void);
+#endif
+
 
 static ngx_command_t  ngx_openssl_commands[] = {
 
@@ -95,6 +107,22 @@
     SSL_load_error_strings();
 
     OpenSSL_add_all_algorithms();
+    
+#if (NGX_THREADS) && defined(OPENSSL_THREADS)
+    if(ngx_install_openssl_locks(log) != NGX_OK)
+    {
+        ngx_ssl_error(NGX_LOG_EMERG, log, 0,
+                      "ngx_install_openssl_locks() failed");
+        return NGX_ERROR;
+    }
+    
+    if(ngx_install_openssl_callbacks(log) != NGX_OK)
+    {
+        ngx_ssl_error(NGX_LOG_EMERG, log, 0,
+                      "ngx_install_openssl_callbacks() failed");
+        return NGX_ERROR;
+    }
+#endif
 
 #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
 #ifndef SSL_OP_NO_COMPRESSION
@@ -2561,4 +2589,92 @@
 {
     EVP_cleanup();
     ENGINE_cleanup();
+    
+#if (NGX_THREADS) && defined(OPENSSL_THREADS)
+    ngx_remove_openssl_callbacks();
+    ngx_remove_openssl_locks();
+#endif
 }
+
+
+#if (NGX_THREADS) && defined(OPENSSL_THREADS)
+int
+ngx_install_openssl_locks(ngx_log_t *log)
+{
+    if(CRYPTO_num_locks() != CRYPTO_NUM_LOCKS)
+    {
+        ngx_ssl_error(NGX_LOG_EMERG, log, 0,
+                      "CRYPTO_num_locks() is not CRYPTO_NUM_LOCKS");
+        return NGX_ERROR;
+    }
+    
+    for(unsigned n = 0; n < CRYPTO_NUM_LOCKS; n++)
+    {
+        g_locks[n] = ngx_mutex_init(log, 0);
+        if (g_locks[n] == NULL) {
+            return NGX_ERROR;
+        }
+    }
+
+    return NGX_OK;
+}
+
+
+static int
+ngx_install_openssl_callbacks(ngx_log_t *log)
+{
+    CRYPTO_set_id_callback(ngx_openssl_thread_id);
+    CRYPTO_set_locking_callback(ngx_openssl_lock_fn);
+
+    return NGX_OK;
+}
+
+
+unsigned long
+ngx_openssl_thread_id(void)
+{
+    return (unsigned long)ngx_thread_self();
+}
+
+
+void
+ngx_openssl_lock_fn(int mode, int idx, const char* file, int line)
+{
+    if (!(idx < 0 || idx > CRYPTO_NUM_LOCKS))
+        return;
+    
+    if ((mode & CRYPTO_LOCK) == CRYPTO_LOCK)
+    {
+        ngx_mutex_lock(g_locks[idx]);
+    }
+    else if ((mode & CRYPTO_UNLOCK) == CRYPTO_UNLOCK)
+    {
+        ngx_mutex_unlock(g_locks[idx]);
+    }
+    
+    /* Hmm... void functions suck */
+}
+
+
+int
+ngx_remove_openssl_callbacks(void)
+{
+    CRYPTO_set_id_callback(NULL);
+    CRYPTO_set_locking_callback(NULL);
+
+    return NGX_OK;
+}
+
+
+int
+ngx_remove_openssl_locks(void)
+{
+    for(unsigned n = 0; n < CRYPTO_NUM_LOCKS; n++)
+    {
+        ngx_mutex_destroy(g_locks[n]);
+        g_locks[n] = NULL;
+    }
+    
+    return NGX_OK;
+}
+#endif
diff -r 68e250ceb06e src/event/ngx_event_openssl.h
--- a/src/event/ngx_event_openssl.h	Tue Nov 19 15:25:24 2013 +0400
+++ b/src/event/ngx_event_openssl.h	Wed Dec 11 12:29:04 2013 -0500
@@ -18,6 +18,7 @@
 #include <openssl/engine.h>
 #include <openssl/evp.h>
 #include <openssl/ocsp.h>
+#include <openssl/opensslconf.h>
 
 #define NGX_SSL_NAME     "OpenSSL"
 
