From ea700d80f5d65f7d6c4cab4ccd09192467b15204 Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Mon, 13 May 2013 16:05:56 +0200 Subject: Cross-platform and (truly) thread-safe OpenSSL initialization. --- src/net/tls/openssl/OpenSSLInitializer.cpp | 70 +++++++++++++----------------- 1 file changed, 30 insertions(+), 40 deletions(-) (limited to 'src/net/tls/openssl/OpenSSLInitializer.cpp') diff --git a/src/net/tls/openssl/OpenSSLInitializer.cpp b/src/net/tls/openssl/OpenSSLInitializer.cpp index dce86179..8238b864 100644 --- a/src/net/tls/openssl/OpenSSLInitializer.cpp +++ b/src/net/tls/openssl/OpenSSLInitializer.cpp @@ -50,79 +50,69 @@ namespace tls { ref * OpenSSLInitializer::sm_mutexes; -int OpenSSLInitializer::sm_initCount(0); -OpenSSLInitializer::OpenSSLInitializer() +OpenSSLInitializer::autoInitializer::autoInitializer() { - initialize(); + // The construction of this unique 'oneTimeInitializer' object will be triggered + // by the 'autoInitializer' objects from the other translation units + static OpenSSLInitializer::oneTimeInitializer oneTimeInitializer; } -OpenSSLInitializer::~OpenSSLInitializer() +OpenSSLInitializer::autoInitializer::~autoInitializer() { - uninitialize(); } -// static -ref OpenSSLInitializer::getMutex() +OpenSSLInitializer::oneTimeInitializer::oneTimeInitializer() { - static ref criticalSection - = vmime::platform::getHandler()->createCriticalSection(); + initialize(); +} - return criticalSection; + +OpenSSLInitializer::oneTimeInitializer::~oneTimeInitializer() +{ + uninitialize(); } // static void OpenSSLInitializer::initialize() { - ref mutex = getMutex(); - vmime::utility::sync::autoLock lock(mutex); - - if (++sm_initCount == 1) - { #if OPENSSL_VERSION_NUMBER >= 0x0907000L - OPENSSL_config(NULL); + OPENSSL_config(NULL); #endif - SSL_load_error_strings(); - SSL_library_init(); - OpenSSL_add_all_algorithms(); + SSL_load_error_strings(); + SSL_library_init(); + OpenSSL_add_all_algorithms(); - unsigned char seed[SEEDSIZE]; - vmime::platform::getHandler()->generateRandomBytes(seed, SEEDSIZE); - RAND_seed(seed, SEEDSIZE); + unsigned char seed[SEEDSIZE]; + vmime::platform::getHandler()->generateRandomBytes(seed, SEEDSIZE); + RAND_seed(seed, SEEDSIZE); - int numMutexes = CRYPTO_num_locks(); - sm_mutexes = new ref [numMutexes]; + int numMutexes = CRYPTO_num_locks(); + sm_mutexes = new ref [numMutexes]; - for (int i = 0 ; i < numMutexes ; ++i) - sm_mutexes[i] = vmime::platform::getHandler()->createCriticalSection(); + for (int i = 0 ; i < numMutexes ; ++i) + sm_mutexes[i] = vmime::platform::getHandler()->createCriticalSection(); - CRYPTO_set_locking_callback(&OpenSSLInitializer::lock); - CRYPTO_set_id_callback(&OpenSSLInitializer::id); - } + CRYPTO_set_locking_callback(&OpenSSLInitializer::lock); + CRYPTO_set_id_callback(&OpenSSLInitializer::id); } // static void OpenSSLInitializer::uninitialize() { - ref mutex = getMutex(); - vmime::utility::sync::autoLock lock(mutex); - - if (--sm_initCount == 0) - { - EVP_cleanup(); - ERR_free_strings(); + EVP_cleanup(); + ERR_free_strings(); - CRYPTO_set_locking_callback(NULL); - CRYPTO_set_id_callback(NULL); + CRYPTO_set_locking_callback(NULL); + CRYPTO_set_id_callback(NULL); - delete [] sm_mutexes; - } + delete [] sm_mutexes; } -- cgit v1.2.3