Add ability to take control of OpenSSL initialization

Signed-off-by: Alan Dunn <amdunn@gmail.com>
Signed-off-by: Roger Meier <roger@apache.org>
diff --git a/lib/cpp/src/thrift/transport/TSSLSocket.cpp b/lib/cpp/src/thrift/transport/TSSLSocket.cpp
index 4b36f8c..fd285db 100644
--- a/lib/cpp/src/thrift/transport/TSSLSocket.cpp
+++ b/lib/cpp/src/thrift/transport/TSSLSocket.cpp
@@ -460,11 +460,14 @@
 // TSSLSocketFactory implementation
 uint64_t TSSLSocketFactory::count_ = 0;
 Mutex    TSSLSocketFactory::mutex_;
+bool     TSSLSocketFactory::manualOpenSSLInitialization_ = false;
 
 TSSLSocketFactory::TSSLSocketFactory(const SSLProtocol& protocol): server_(false) {
   Guard guard(mutex_);
   if (count_ == 0) {
-    initializeOpenSSL();
+    if (!manualOpenSSLInitialization_) {
+      initializeOpenSSL();
+    }
     randomize();
   }
   count_++;
@@ -475,7 +478,7 @@
   Guard guard(mutex_);
   ctx_.reset();
   count_--;
-  if (count_ == 0) {
+  if (count_ == 0 && !manualOpenSSLInitialization_) {
     cleanupOpenSSL();
   }
 }
diff --git a/lib/cpp/src/thrift/transport/TSSLSocket.h b/lib/cpp/src/thrift/transport/TSSLSocket.h
index eca9591..a4b805b 100644
--- a/lib/cpp/src/thrift/transport/TSSLSocket.h
+++ b/lib/cpp/src/thrift/transport/TSSLSocket.h
@@ -44,15 +44,17 @@
 /**
  * Initialize OpenSSL library.  This function, or some other
  * equivalent function to initialize OpenSSL, must be called before
- * TSSLSocket is used.  Currently TSSLSocketFactory automatically
- * calls this function, so you should not.
+ * TSSLSocket is used.  If you set TSSLSocketFactory to use manual
+ * OpenSSL initialization, you should call this function or otherwise
+ * ensure OpenSSL is initialized yourself.
  */
 void initializeOpenSSL();
 /**
  * Cleanup OpenSSL library.  This function should be called to clean
- * up OpenSSL after use of OpenSSL functionality is finished.
- * Currently TSSLSocketFactory automatically calls this function, so
- * you should not.
+ * up OpenSSL after use of OpenSSL functionality is finished.  If you
+ * set TSSLSocketFactory to use manual OpenSSL initialization, you
+ * should call this function yourself or ensure that whatever
+ * initialized OpenSSL cleans it up too.
  */
 void cleanupOpenSSL();
 
@@ -216,6 +218,9 @@
   virtual void access(boost::shared_ptr<AccessManager> manager) {
     access_ = manager;
   }
+  static void setManualOpenSSLInitialization(bool manualOpenSSLInitialization) {
+    manualOpenSSLInitialization_ = manualOpenSSLInitialization;
+  }
  protected:
   boost::shared_ptr<SSLContext> ctx_;
 
@@ -232,6 +237,7 @@
   boost::shared_ptr<AccessManager> access_;
   static concurrency::Mutex mutex_;
   static uint64_t count_;
+  static bool manualOpenSSLInitialization_;
   void setup(boost::shared_ptr<TSSLSocket> ssl);
   static int passwordCallback(char* password, int size, int, void* data);
 };