Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

crypto: make module thread-safe

  • Loading branch information...
commit 97cada0e6a130791ceafaa750f9009d8fdaaadbb 1 parent 0ba8f05
Ben Noordhuis bnoordhuis authored
Showing with 74 additions and 0 deletions.
  1. +74 −0 src/node_crypto.cc
74 src/node_crypto.cc
View
@@ -36,6 +36,13 @@
#include <errno.h>
+/* Sigh. */
+#ifdef _WIN32
+# include <windows.h>
+#else
+# include <pthread.h>
+#endif
+
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
# define OPENSSL_CONST const
#else
@@ -76,6 +83,69 @@ static Persistent<String> ext_key_usage_symbol;
static Persistent<FunctionTemplate> secure_context_constructor;
+#ifdef _WIN32
+
+static HANDLE* locks;
+
+
+static void crypto_lock_init(void) {
+ int i, n;
+
+ n = CRYPTO_num_locks();
+ locks = new HANDLE[n];
+
+ for (i = 0; i < n; i++)
+ if (!(locks[i] = CreateMutex(NULL, FALSE, NULL)))
+ abort();
+}
+
+
+static void crypto_lock_cb(int mode, int n, const char* file, int line) {
+ if (mode & CRYPTO_LOCK)
+ WaitForSingleObject(locks[type], INFINITE);
+ else
+ ReleaseMutex(locks[type]);
+}
+
+
+static unsigned long crypto_id_cb(void) {
+ return (unsigned long) GetCurrentThreadId();
+}
+
+#else /* !_WIN32 */
+
+static pthread_rwlock_t* locks;
+
+
+static void crypto_lock_init(void) {
+ int i, n;
+
+ n = CRYPTO_num_locks();
+ locks = new pthread_rwlock_t[n];
+
+ for (i = 0; i < n; i++)
+ if (pthread_rwlock_init(locks + i, NULL))
+ abort();
+}
+
+
+static void crypto_lock_cb(int mode, int n, const char* file, int line) {
+ if (mode & CRYPTO_LOCK) {
+ if (mode & CRYPTO_READ) pthread_rwlock_rdlock(locks + n);
+ if (mode & CRYPTO_WRITE) pthread_rwlock_wrlock(locks + n);
+ } else {
+ pthread_rwlock_unlock(locks + n);
+ }
+}
+
+
+static unsigned long crypto_id_cb(void) {
+ return (unsigned long) pthread_self();
+}
+
+#endif /* !_WIN32 */
+
+
void SecureContext::Initialize(Handle<Object> target) {
HandleScope scope;
@@ -4196,6 +4266,10 @@ void InitCrypto(Handle<Object> target) {
SSL_load_error_strings();
ERR_load_crypto_strings();
+ crypto_lock_init();
+ CRYPTO_set_locking_callback(crypto_lock_cb);
+ CRYPTO_set_id_callback(crypto_id_cb);
+
// Turn off compression. Saves memory - do it in userland.
#if !defined(OPENSSL_NO_COMP)
STACK_OF(SSL_COMP)* comp_methods =
Please sign in to comment.
Something went wrong with that request. Please try again.