You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by pe...@apache.org on 2001/10/24 01:09:32 UTC

cvs commit: xml-xerces/c/src/util XMLRegisterCleanup.hpp Makefile.in PlatformUtils.cpp XMLException.cpp

peiyongz    01/10/23 16:09:32

  Modified:    c/src/util Makefile.in PlatformUtils.cpp XMLException.cpp
  Added:       c/src/util XMLRegisterCleanup.hpp
  Log:
  [Bug#880] patch to PlatformUtils:init()/term() and related. from Mark Weaver
  
  Revision  Changes    Path
  1.48      +4 -0      xml-xerces/c/src/util/Makefile.in
  
  Index: Makefile.in
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/util/Makefile.in,v
  retrieving revision 1.47
  retrieving revision 1.48
  diff -u -r1.47 -r1.48
  --- Makefile.in	2001/10/02 16:07:45	1.47
  +++ Makefile.in	2001/10/23 23:09:32	1.48
  @@ -55,6 +55,9 @@
   #
   #
   # $Log: Makefile.in,v $
  +# Revision 1.48  2001/10/23 23:09:32  peiyongz
  +# [Bug#880] patch to PlatformUtils:init()/term() and related. from Mark Weaver
  +#
   # Revision 1.47  2001/10/02 16:07:45  tng
   # typo: fix extra spaces after the separator that led to make error
   #
  @@ -371,6 +374,7 @@
       XMLFloat.hpp \
       XMLMsgLoader.hpp \
       XMLNetAccessor.hpp \
  +    XMLRegisterCleanup.hpp \
       XMLString.hpp \
       XMLUCS4Transcoder.hpp \
       XMLUri.hpp \
  
  
  
  1.14      +34 -1     xml-xerces/c/src/util/PlatformUtils.cpp
  
  Index: PlatformUtils.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/util/PlatformUtils.cpp,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- PlatformUtils.cpp	2001/05/11 13:26:27	1.13
  +++ PlatformUtils.cpp	2001/10/23 23:09:32	1.14
  @@ -56,6 +56,9 @@
   
   /*
    * $Log: PlatformUtils.cpp,v $
  + * Revision 1.14  2001/10/23 23:09:32  peiyongz
  + * [Bug#880] patch to PlatformUtils:init()/term() and related. from Mark Weaver
  + *
    * Revision 1.13  2001/05/11 13:26:27  tng
    * Copyright update.
    *
  @@ -127,6 +130,7 @@
   #include <util/XMLUni.hpp>
   #include <internal/XMLReader.hpp>
   #include <util/RuntimeException.hpp>
  +#include <util/XMLRegisterCleanup.hpp>
   
   
   // ---------------------------------------------------------------------------
  @@ -140,6 +144,21 @@
   static RefVectorOf<XMLDeleter>* gLazyData;
   static short                    gInitFlag = 0;
   
  +// ---------------------------------------------------------------------------
  +//  Global data
  +//
  +//	gXMLCleanupList
  +//		This is a list of cleanup functions to be called on 
  +//		XMLPlatformUtils::Terminate.  Their function is to reset static
  +//		data in classes that use it.
  +//
  +//	gXMLCleanupListMutex
  +//		This is a mutex that will be used to synchronise access to the global
  +//		static data cleanup list
  +// ---------------------------------------------------------------------------
  +XMLRegisterCleanup*	gXMLCleanupList = 0;
  +XMLMutex*			gXMLCleanupListMutex = 0;
  +
   
   // ---------------------------------------------------------------------------
   //  XMLPlatformUtils: Static Data Members
  @@ -176,6 +195,9 @@
       // Create the local sync mutex
       gSyncMutex = new XMLMutex;
   
  +	// Create the mutex for the static data cleanup list
  +	gXMLCleanupListMutex = new XMLMutex;
  +
       // Create the array for saving lazily allocated objects to be deleted at termination
       gLazyData= new RefVectorOf<XMLDeleter>(512);
   
  @@ -251,6 +273,17 @@
       delete gSyncMutex;
       gSyncMutex = 0;
   
  +	// Clean up statically allocated, lazily cleaned data in each class
  +	// that has registered for it.
  +	// Note that calling doCleanup() also unregisters the cleanup
  +	// function, so that we are chewing the list down to nothing here
  +	while (gXMLCleanupList)
  +		gXMLCleanupList->doCleanup();
  +
  +	// Clean up the mutex for accessing gXMLCleanupList
  +	delete gXMLCleanupListMutex;
  +	gXMLCleanupListMutex = 0;
  +
       //
       //  And do platform termination. This cannot do use any XML services
       //  at all, it can only clean up local stuff. It it reports an error,
  @@ -259,7 +292,7 @@
       platformTerm();
   
       // And say we are no longer initialized
  -    gInitFlag = false;
  +    gInitFlag = 0;
   }
   
   
  
  
  
  1.7       +40 -24    xml-xerces/c/src/util/XMLException.cpp
  
  Index: XMLException.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/util/XMLException.cpp,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- XMLException.cpp	2000/07/25 22:28:15	1.6
  +++ XMLException.cpp	2001/10/23 23:09:32	1.7
  @@ -55,7 +55,7 @@
    */
   
   /*
  - * $Id: XMLException.cpp,v 1.6 2000/07/25 22:28:15 aruna1 Exp $
  + * $Id: XMLException.cpp,v 1.7 2001/10/23 23:09:32 peiyongz Exp $
    */
   
   
  @@ -64,9 +64,9 @@
   // ---------------------------------------------------------------------------
   #include <util/Mutexes.hpp>
   #include <util/PlatformUtils.hpp>
  -#include <util/XMLDeleterFor.hpp>
   #include <util/XMLException.hpp>
   #include <util/XMLMsgLoader.hpp>
  +#include <util/XMLRegisterCleanup.hpp>
   #include <util/XMLString.hpp>
   #include <util/XMLUniDefs.hpp>
   #include <util/XMLUni.hpp>
  @@ -90,35 +90,47 @@
   
   
   // ---------------------------------------------------------------------------
  +//  Local, static data
  +// ---------------------------------------------------------------------------
  +static XMLMsgLoader* sLoader = 0;
  +static XMLMutex* sMsgMutex = 0;
  +
  +// ---------------------------------------------------------------------------
   //  Local, static functions
   // ---------------------------------------------------------------------------
   
  +// -----------------------------------------------------------------------
  +//  Reinitialise the message mutex
  +// -----------------------------------------------------------------------
  +static void reinitMsgMutex()
  +{
  +	delete sMsgMutex;
  +	sMsgMutex = 0;
  +}
  +
   //
   //  We need to fault in this mutex. But, since its used for synchronization
   //  itself, we have to do this the low level way using a compare and swap.
   //
   static XMLMutex& gMsgMutex()
   {
  -    static XMLMutex* msgMutex = 0;
  -    if (!msgMutex)
  +	static XMLRegisterCleanup msgMutexCleanup;
  +    if (!sMsgMutex)
       {
           XMLMutex* tmpMutex = new XMLMutex;
  -        if (XMLPlatformUtils::compareAndSwap((void**)&msgMutex, tmpMutex, 0))
  +        if (XMLPlatformUtils::compareAndSwap((void**)&sMsgMutex, tmpMutex, 0))
           {
               // Some other thread beat us to it, so let's clean up ours.
               delete tmpMutex;
           }
           else
           {
  -            // This is the real mutex.  Register it for deletion at Termination.
  -            XMLPlatformUtils::registerLazyData
  -                (
  -                new XMLDeleterFor<XMLMutex>(msgMutex)
  -                );
  +            // This is the real mutex.  Register it for cleanup at Termination.
  +			msgMutexCleanup.registerCleanup(reinitMsgMutex);
           }
           
       }
  -    return *msgMutex;
  +    return *sMsgMutex;
   }
   
   
  @@ -127,6 +139,15 @@
   //  Local methods
   // ---------------------------------------------------------------------------
   
  +// -----------------------------------------------------------------------
  +//  Reinitialise the message loader
  +// -----------------------------------------------------------------------
  +static void reinitMsgLoader()
  +{
  +	delete sLoader;
  +	sLoader = 0;
  +}
  +
   //
   //  This method is a lazy evaluator for the message loader for exception
   //  messages.
  @@ -136,29 +157,24 @@
   //
   static XMLMsgLoader& gGetMsgLoader()
   {
  +	static XMLRegisterCleanup msgLoaderCleanup;
  +
       // Fault it in on first request
  -    static XMLMsgLoader* gLoader = 0;
  -    if (!gLoader)
  +    if (!sLoader)
       {
  -        gLoader = XMLPlatformUtils::loadMsgSet(XMLUni::fgExceptDomain);
  -        if (!gLoader)
  +        sLoader = XMLPlatformUtils::loadMsgSet(XMLUni::fgExceptDomain);
  +        if (!sLoader)
               XMLPlatformUtils::panic(XMLPlatformUtils::Panic_CantLoadMsgDomain);
   
           //
  -        // Register this XMLMsgLoader for deletion at Termination.
  +        // Register this XMLMsgLoader for cleanup at Termination.
           //
  -        XMLPlatformUtils::registerLazyData
  -            (
  -            new XMLDeleterFor<XMLMsgLoader>(gLoader)
  -            );
  -        
  +        msgLoaderCleanup.registerCleanup(reinitMsgLoader);
       }
       
       // We got it, so return it
  -    return *gLoader;
  +    return *sLoader;
   }
  -
  -
   
   // ---------------------------------------------------------------------------
   //  XMLException: Virtual destructor
  
  
  
  1.1                  xml-xerces/c/src/util/XMLRegisterCleanup.hpp
  
  Index: XMLRegisterCleanup.hpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   * 
   * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
   * reserved.
   * 
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   * 
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   * 
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   * 
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   * 
   * 4. The names "Xerces" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache\@apache.org.
   * 
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   * 
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   * 
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation, and was
   * originally based on software copyright (c) 1999, International
   * Business Machines, Inc., http://www.ibm.com .  For more information
   * on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  #if !defined(XMLREGISTERCLEANUP_HPP)
  #define XMLREGISTERCLEANUP_HPP
  
  #include <util/Mutexes.hpp>
  
  // 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
  class XMLRegisterCleanup;
  extern XMLRegisterCleanup* gXMLCleanupList;
  
  // 
  //  For internal use only.
  //
  //  This class is used by the platform utilities class to support 
  //  reinitialisation of global/static data which is lazily created. 
  //  Since that data is widely spread out the platform utilities
  //  class cannot know about them directly. So, the code that creates such
  //  objects creates an registers a cleanup for the object. The platform
  //  termination call will iterate the list and delete the objects.
  //
  //  N.B. These objects need to be statically allocated.  I couldn't think
  //  of a neat way of ensuring this - can anyone else?
  
  class XMLRegisterCleanup
  {
  public :
  	// The cleanup function to be called on XMLPlatformUtils::Terminate()
  	typedef void (*XMLCleanupFn)();
  	
  	void 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();
  			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 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 unregisterCleanup() {
  		gXMLCleanupListMutex->lock();
  
  		// 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
  		resetCleanup();
  	}
  
  	// The default constructor sets a state that ensures that this object
  	// will do nothing
  	XMLRegisterCleanup()
  	{
  		resetCleanup();
  	}
  
  private:
  	// This is the cleanup function to be called
  	XMLCleanupFn m_cleanupFn;
  
  	// These are list pointers to the next/prev cleanup function to be called
  	XMLRegisterCleanup *m_nextCleanup, *m_prevCleanup;
  
  	// This function reinitialises the object to the default state
  	void resetCleanup() {
  		m_nextCleanup = 0;
  		m_prevCleanup = 0;
  		m_cleanupFn = 0;
  	}
  };
  
  #endif
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org