diff options
author | Vincent Richard <[email protected]> | 2013-05-13 14:05:56 +0000 |
---|---|---|
committer | Vincent Richard <[email protected]> | 2013-05-13 14:05:56 +0000 |
commit | ea700d80f5d65f7d6c4cab4ccd09192467b15204 (patch) | |
tree | da40c4504649b2b318c019e7d35ee856536d6abb /src/net/tls/openssl/OpenSSLInitializer.cpp | |
parent | Put generated header files in a separate list. (diff) | |
download | vmime-ea700d80f5d65f7d6c4cab4ccd09192467b15204.tar.gz vmime-ea700d80f5d65f7d6c4cab4ccd09192467b15204.zip |
Cross-platform and (truly) thread-safe OpenSSL initialization.
Diffstat (limited to 'src/net/tls/openssl/OpenSSLInitializer.cpp')
-rw-r--r-- | src/net/tls/openssl/OpenSSLInitializer.cpp | 70 |
1 files changed, 30 insertions, 40 deletions
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 <vmime::utility::sync::criticalSection >* 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 <vmime::utility::sync::criticalSection> OpenSSLInitializer::getMutex() +OpenSSLInitializer::oneTimeInitializer::oneTimeInitializer() { - static ref <vmime::utility::sync::criticalSection> criticalSection - = vmime::platform::getHandler()->createCriticalSection(); + initialize(); +} - return criticalSection; + +OpenSSLInitializer::oneTimeInitializer::~oneTimeInitializer() +{ + uninitialize(); } // static void OpenSSLInitializer::initialize() { - ref <vmime::utility::sync::criticalSection> mutex = getMutex(); - vmime::utility::sync::autoLock <vmime::utility::sync::criticalSection> 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 <vmime::utility::sync::criticalSection>[numMutexes]; + int numMutexes = CRYPTO_num_locks(); + sm_mutexes = new ref <vmime::utility::sync::criticalSection>[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 <vmime::utility::sync::criticalSection> mutex = getMutex(); - vmime::utility::sync::autoLock <vmime::utility::sync::criticalSection> 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; } |