diff options
Diffstat (limited to 'rpc/rpc-transport')
-rw-r--r-- | rpc/rpc-transport/socket/src/socket.c | 64 |
1 files changed, 39 insertions, 25 deletions
diff --git a/rpc/rpc-transport/socket/src/socket.c b/rpc/rpc-transport/socket/src/socket.c index dd7f5d3b77e..02a0a86526a 100644 --- a/rpc/rpc-transport/socket/src/socket.c +++ b/rpc/rpc-transport/socket/src/socket.c @@ -3962,15 +3962,7 @@ out: } -/* - * Unlike the stuff in init, this only needs to be called once GLOBALLY no - * matter how many translators/sockets we end up with. Conveniently, - * __attribute__(constructor) provides exactly those semantics in a pretty - * portable fashion. - */ - static pthread_mutex_t *lock_array = NULL; -static gf_boolean_t constructor_ok = _gf_false; static void locking_func (int mode, int type, const char *file, int line) @@ -4007,29 +3999,61 @@ legacy_threadid_func (void) } #endif -static void __attribute__((constructor)) +static void init_openssl_mt (void) { int num_locks = CRYPTO_num_locks(); int i; + if (lock_array) { + /* this only needs to be initialized once GLOBALLY no + matter how many translators/sockets we end up with. */ + return; + } + + SSL_library_init(); + SSL_load_error_strings(); + lock_array = GF_CALLOC (num_locks, sizeof(pthread_mutex_t), gf_sock_mt_lock_array); if (lock_array) { for (i = 0; i < num_locks; ++i) { pthread_mutex_init (&lock_array[i], NULL); } - CRYPTO_set_locking_callback (locking_func); #if HAVE_CRYPTO_THREADID CRYPTO_THREADID_set_callback (threadid_func); #else /* older openssl */ CRYPTO_set_id_callback (legacy_threadid_func); #endif - constructor_ok = _gf_true; + CRYPTO_set_locking_callback (locking_func); } - SSL_library_init(); - SSL_load_error_strings(); +} + +static void __attribute__((destructor)) +fini_openssl_mt (void) +{ + int i; + + if (!lock_array) { + return; + } + + CRYPTO_set_locking_callback(NULL); +#if HAVE_CRYPTO_THREADID + CRYPTO_THREADID_set_callback (NULL); +#else /* older openssl */ + CRYPTO_set_id_callback (NULL); +#endif + + for (i = 0; i < CRYPTO_num_locks(); ++i) { + pthread_mutex_destroy (&lock_array[i]); + } + + GF_FREE (lock_array); + lock_array = NULL; + + ERR_free_strings(); } static void @@ -4319,18 +4343,6 @@ socket_init (rpc_transport_t *this) if (priv->ssl_enabled || priv->mgmt_ssl) { BIO *bio = NULL; - /* - * The right time to check this is after all of our relevant - * fields have been set, but before we start issuing OpenSSL - * calls for the current translator. In other words, now. - */ - if (!constructor_ok) { - gf_log (this->name, GF_LOG_ERROR, - "can't initialize TLS socket (%s)", - "static constructor failed"); - goto err; - } - #if HAVE_TLSV1_2_METHOD priv->ssl_meth = (SSL_METHOD *)TLSv1_2_method(); #else @@ -4548,6 +4560,8 @@ init (rpc_transport_t *this) { int ret = -1; + init_openssl_mt(); + ret = socket_init (this); if (ret == -1) { |