From: Scott Cantor Date: Mon, 6 Jun 2011 19:18:02 +0000 (+0000) Subject: https://issues.shibboleth.net/jira/browse/CPPOST-66 X-Git-Tag: 2.4.2~6 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fcpp-opensaml.git;a=commitdiff_plain;h=7f06873592fcb03326301a0c7cc81bba1b87741d https://issues.shibboleth.net/jira/browse/CPPOST-66 --- diff --git a/saml/SAMLConfig.cpp b/saml/SAMLConfig.cpp index eac17f8..049e533 100644 --- a/saml/SAMLConfig.cpp +++ b/saml/SAMLConfig.cpp @@ -1,4 +1,3 @@ - /* * Copyright 2001-2010 Internet2 * @@ -56,6 +55,7 @@ #include #include #include +#include #include #include @@ -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) diff --git a/saml/internal.h b/saml/internal.h index 2392e16..2946c10 100644 --- a/saml/internal.h +++ b/saml/internal.h @@ -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 diff --git a/samltest/samltest.h b/samltest/samltest.h index e817f72..c996bde 100644 --- a/samltest/samltest.h +++ b/samltest/samltest.h @@ -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 );