summaryrefslogtreecommitdiff
path: root/cpp/src/IceSSL/Instance.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/IceSSL/Instance.cpp')
-rw-r--r--cpp/src/IceSSL/Instance.cpp29
1 files changed, 22 insertions, 7 deletions
diff --git a/cpp/src/IceSSL/Instance.cpp b/cpp/src/IceSSL/Instance.cpp
index 51e7a76b51b..03bb4010062 100644
--- a/cpp/src/IceSSL/Instance.cpp
+++ b/cpp/src/IceSSL/Instance.cpp
@@ -54,6 +54,12 @@ public:
{
delete staticMutex;
staticMutex = 0;
+
+ if(locks)
+ {
+ delete[] locks;
+ locks = 0;
+ }
}
};
@@ -70,6 +76,7 @@ extern "C"
void
IceSSL_opensslLockCallback(int mode, int n, const char* file, int line)
{
+ assert(locks);
if(mode & CRYPTO_LOCK)
{
locks[n].lock();
@@ -170,9 +177,12 @@ IceSSL::Instance::Instance(const CommunicatorPtr& communicator) :
//
// Create the mutexes and set the callbacks.
//
- locks = new IceUtil::Mutex[CRYPTO_num_locks()];
- CRYPTO_set_locking_callback(IceSSL_opensslLockCallback);
- CRYPTO_set_id_callback(IceSSL_opensslThreadIdCallback);
+ if(!locks)
+ {
+ locks = new IceUtil::Mutex[CRYPTO_num_locks()];
+ CRYPTO_set_locking_callback(IceSSL_opensslLockCallback);
+ CRYPTO_set_id_callback(IceSSL_opensslThreadIdCallback);
+ }
//
// Load human-readable error messages.
@@ -274,10 +284,15 @@ IceSSL::Instance::~Instance()
if(--instanceCount == 0)
{
- CRYPTO_set_locking_callback(0);
- CRYPTO_set_id_callback(0);
- delete[] locks;
- locks = 0;
+ //
+ // NOTE: We can't destroy the locks here: threads wich might have called openssl methods
+ // might access openssl locks upon termination (from DllMain/THREAD_DETACHED). Instead,
+ // we release the locks in the ~Init() static destructor. See bug #4156.
+ //
+ //CRYPTO_set_locking_callback(0);
+ //CRYPTO_set_id_callback(0);
+ //delete[] locks;
+ //locks = 0;
CRYPTO_cleanup_all_ex_data();
RAND_cleanup();