blob: b93bf63503fa6474f54e8971a7523f04139bb541 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* $Id: XMLRegisterCleanup.cpp 568078 2007-08-21 11:43:25Z amassari $
*/
// ---------------------------------------------------------------------------
// Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/XMLRegisterCleanup.hpp>
XERCES_CPP_NAMESPACE_BEGIN
// This is a mutex for exclusive use by this class
extern XMLMutex* gXMLCleanupListMutex;
// This is the head of a list of XMLRegisterCleanup objects that
// is used during XMLPlatformUtils::Terminate() to find objects to
// clean up
extern XMLRegisterCleanup* gXMLCleanupList;
void XMLRegisterCleanup::doCleanup()
{
// When performing cleanup, we only do this once, but we can
// cope if somehow we have been called twice.
if (m_cleanupFn)
m_cleanupFn();
// We need to remove "this" from the list
// irregardless of the cleanup Function
unregisterCleanup();
}
// This function is called during initialisation of static data to
// register a function to be called on XMLPlatformUtils::Terminate.
// It gives an object that uses static data an opportunity to reset
// such data.
void XMLRegisterCleanup::registerCleanup(XMLCleanupFn cleanupFn)
{
// Store the cleanup function
m_cleanupFn = cleanupFn;
// Add this object to the list head, if it is not already
// present - which it shouldn't be.
// This is done under a mutex to ensure thread safety.
gXMLCleanupListMutex->lock();
if (!m_nextCleanup && !m_prevCleanup)
{
m_nextCleanup = gXMLCleanupList;
gXMLCleanupList = this;
if (m_nextCleanup)
m_nextCleanup->m_prevCleanup = this;
}
gXMLCleanupListMutex->unlock();
}
// This function can be called either from XMLPlatformUtils::Terminate
// to state that the cleanup has been performed and should not be
// performed again, or from code that you have written that determines
// that cleanup is no longer necessary.
void XMLRegisterCleanup::unregisterCleanup()
{
gXMLCleanupListMutex->lock();
//
// To protect against some compiler's (eg hp11) optimization
// to change "this" as they update gXMLCleanupList
//
// refer to
// void XMLPlatformUtils::Terminate()
// ...
// while (gXMLCleanupList)
// gXMLCleanupList->doCleanup();
//
XMLRegisterCleanup *tmpThis = (XMLRegisterCleanup*) this;
// Unlink this object from the cleanup list
if (m_nextCleanup)
m_nextCleanup->m_prevCleanup = m_prevCleanup;
if (!m_prevCleanup)
gXMLCleanupList = m_nextCleanup;
else
m_prevCleanup->m_nextCleanup = m_nextCleanup;
gXMLCleanupListMutex->unlock();
// Reset the object to the default state
tmpThis->resetCleanup();
}
// The default constructor sets a state that ensures that this object
// will do nothing
XMLRegisterCleanup::XMLRegisterCleanup()
{
resetCleanup();
}
// This function reinitialises the object to the default state
void XMLRegisterCleanup::resetCleanup()
{
m_nextCleanup = 0;
m_prevCleanup = 0;
m_cleanupFn = 0;
}
XERCES_CPP_NAMESPACE_END