https://issues.shibboleth.net/jira/browse/CPPOST-66
authorScott Cantor <cantor.2@osu.edu>
Mon, 6 Jun 2011 19:18:02 +0000 (19:18 +0000)
committerScott Cantor <cantor.2@osu.edu>
Mon, 6 Jun 2011 19:18:02 +0000 (19:18 +0000)
saml/SAMLConfig.cpp
saml/internal.h
samltest/samltest.h

index eac17f8..049e533 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  *  Copyright 2001-2010 Internet2
  * 
@@ -56,6 +55,7 @@
 #include <xmltooling/signature/Signature.h>
 #include <xmltooling/util/NDC.h>
 #include <xmltooling/util/PathResolver.h>
+#include <xmltooling/util/Threads.h>
 
 #include <xsec/enc/XSECCryptoException.hpp>
 #include <xsec/enc/XSECCryptoProvider.hpp>
@@ -123,16 +123,40 @@ void SAMLConfig::setArtifactMap(ArtifactMap* artifactMap)
     m_artifactMap = artifactMap;
 }
 
+SAMLInternalConfig::SAMLInternalConfig() : m_initCount(0), m_lock(Mutex::create())
+{
+}
+
+SAMLInternalConfig::~SAMLInternalConfig()
+{
+    delete m_lock;
+}
+
 bool SAMLInternalConfig::init(bool initXMLTooling)
 {
 #ifdef _DEBUG
     xmltooling::NDC ndc("init");
 #endif
-    Category& log=Category::getInstance(SAML_LOGCAT".SAMLConfig");
+    Category& log=Category::getInstance(SAML_LOGCAT".Config");
+
+    Lock initLock(m_lock);
+
+    if (m_initCount == LONG_MAX) {
+        log.crit("library initialized too many times");
+        return false;
+    }
+
+    if (m_initCount >= 1) {
+        ++m_initCount;
+        return true;
+    }
+
     log.debug("library initialization started");
 
-    if (initXMLTooling)
-        XMLToolingConfig::getConfig().init();
+    if (initXMLTooling && !XMLToolingConfig::getConfig().init()) {
+        return false;
+    }
+
     XMLToolingConfig::getConfig().getPathResolver()->setDefaultPackageName("opensaml");
 
     REGISTER_XMLTOOLING_EXCEPTION_FACTORY(ArtifactException,opensaml);
@@ -157,6 +181,7 @@ bool SAMLInternalConfig::init(bool initXMLTooling)
     registerSecurityPolicyRules();
 
     log.info("%s library initialization complete", PACKAGE_STRING);
+    ++m_initCount;
     return true;
 }
 
@@ -165,7 +190,15 @@ void SAMLInternalConfig::term(bool termXMLTooling)
 #ifdef _DEBUG
     xmltooling::NDC ndc("term");
 #endif
-    Category& log=Category::getInstance(SAML_LOGCAT".SAMLConfig");
+
+    Lock initLock(m_lock);
+    if (m_initCount == 0) {
+        Category::getInstance(SAML_LOGCAT".Config").crit("term without corresponding init");
+        return;
+    }
+    else if (--m_initCount > 0) {
+        return;
+    }
 
     MessageDecoderManager.deregisterFactories();
     MessageEncoderManager.deregisterFactories();
@@ -180,7 +213,7 @@ void SAMLInternalConfig::term(bool termXMLTooling)
     if (termXMLTooling)
         XMLToolingConfig::getConfig().term();
     
-    log.info("%s library shutdown complete", PACKAGE_STRING);
+    Category::getInstance(SAML_LOGCAT".Config").info("%s library shutdown complete", PACKAGE_STRING);
 }
 
 void SAMLInternalConfig::generateRandomBytes(void* buf, unsigned int len)
index 2392e16..2946c10 100644 (file)
@@ -80,13 +80,18 @@ using namespace xercesc;
 
 #define SAML_LOGCAT "OpenSAML"
 
+namespace xmltooling {
+    class XMLTOOL_API Mutex;
+};
+
 namespace opensaml {
     
     /// @cond OFF
-    class SAMLInternalConfig : public SAMLConfig
+    class SAML_DLLLOCAL SAMLInternalConfig : public SAMLConfig
     {
     public:
-        SAMLInternalConfig() {}
+        SAMLInternalConfig();
+        ~SAMLInternalConfig();
 
         static SAMLInternalConfig& getInternalConfig();
 
@@ -98,7 +103,10 @@ namespace opensaml {
         void generateRandomBytes(std::string& buf, unsigned int len);
         XMLCh* generateIdentifier();
         std::string hashSHA1(const char* data, bool toHex=false);
+
     private:
+        int m_initCount;
+        xmltooling::Mutex* m_lock;
     };
     /// @endcond
 
index e817f72..c996bde 100644 (file)
@@ -35,6 +35,8 @@ public:
         XMLToolingConfig::getConfig().log_config();
         if (!SAMLConfig::getConfig().init())
             return false;
+        if (!SAMLConfig::getConfig().init())    // should be a no-op
+            return false;
         XMLToolingConfig::getConfig().setReplayCache(new ReplayCache());
         XMLToolingConfig::getConfig().setTemplateEngine(new TemplateEngine());
         SAMLConfig::getConfig().setArtifactMap(new ArtifactMap());
@@ -47,7 +49,9 @@ public:
         return true;
     }
     bool tearDownWorld() {
+        SAMLConfig::getConfig().term();     // should be a no-op
         SAMLConfig::getConfig().term();
+        SAMLConfig::getConfig().term();     // shouldn't cause a crash
 #if defined(_MSC_VER ) && defined(SAML_LEAKCHECK)
        _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
        _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );