Main Page   Class Hierarchy   Compound List   File List   Compound Members  

XMLRegisterCleanup.hpp

00001 /*
00002  * The Apache Software License, Version 1.1
00003  * 
00004  * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
00005  * reserved.
00006  * 
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  * 
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer. 
00013  * 
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in
00016  *    the documentation and/or other materials provided with the
00017  *    distribution.
00018  * 
00019  * 3. The end-user documentation included with the redistribution,
00020  *    if any, must include the following acknowledgment:  
00021  *       "This product includes software developed by the
00022  *        Apache Software Foundation (http://www.apache.org/)."
00023  *    Alternately, this acknowledgment may appear in the software itself,
00024  *    if and wherever such third-party acknowledgments normally appear.
00025  * 
00026  * 4. The names "Xerces" and "Apache Software Foundation" must
00027  *    not be used to endorse or promote products derived from this
00028  *    software without prior written permission. For written 
00029  *    permission, please contact apache\@apache.org.
00030  * 
00031  * 5. Products derived from this software may not be called "Apache",
00032  *    nor may "Apache" appear in their name, without prior written
00033  *    permission of the Apache Software Foundation.
00034  * 
00035  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
00036  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00037  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00038  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
00039  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00040  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00041  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00042  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00043  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00044  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00045  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00046  * SUCH DAMAGE.
00047  * ====================================================================
00048  * 
00049  * This software consists of voluntary contributions made by many
00050  * individuals on behalf of the Apache Software Foundation, and was
00051  * originally based on software copyright (c) 1999, International
00052  * Business Machines, Inc., http://www.ibm.com .  For more information
00053  * on the Apache Software Foundation, please see
00054  * <http://www.apache.org/>.
00055  */
00056 
00057 /*
00058  * $Id: XMLRegisterCleanup.hpp,v 1.1 2002/05/11 21:20:03 bhavani Exp $
00059  * $Log: XMLRegisterCleanup.hpp,v $
00060  * Revision 1.1  2002/05/11 21:20:03  bhavani
00061  * CR#CR062582# adding xercesc 1.7 file
00062  *
00063  * Revision 1.1.1.1  2002/02/01 22:22:15  peiyongz
00064  * sane_include
00065  *
00066  * Revision 1.4  2001/10/25 21:55:29  peiyongz
00067  * copy ctor explicity declared private to prevent supprise.
00068  *
00069  * Revision 1.3  2001/10/24 18:13:06  peiyongz
00070  * CVS tag added
00071  *
00072  *
00073  */
00074 
00075 #if !defined(XMLREGISTERCLEANUP_HPP)
00076 #define XMLREGISTERCLEANUP_HPP
00077 
00078 #include <xercesc/util/Mutexes.hpp>
00079 
00080 // This is a mutex for exclusive use by this class
00081 extern XMLMutex* gXMLCleanupListMutex;
00082 
00083 // This is the head of a list of XMLRegisterCleanup objects that
00084 // is used during XMLPlatformUtils::Terminate() to find objects to
00085 // clean up
00086 class XMLRegisterCleanup;
00087 extern XMLRegisterCleanup* gXMLCleanupList;
00088 
00089 // 
00090 //  For internal use only.
00091 //
00092 //  This class is used by the platform utilities class to support 
00093 //  reinitialisation of global/static data which is lazily created. 
00094 //  Since that data is widely spread out the platform utilities
00095 //  class cannot know about them directly. So, the code that creates such
00096 //  objects creates an registers a cleanup for the object. The platform
00097 //  termination call will iterate the list and delete the objects.
00098 //
00099 //  N.B. These objects need to be statically allocated.  I couldn't think
00100 //  of a neat way of ensuring this - can anyone else?
00101 
00102 class XMLRegisterCleanup
00103 {
00104 public :
00105         // The cleanup function to be called on XMLPlatformUtils::Terminate()
00106         typedef void (*XMLCleanupFn)();
00107         
00108         void doCleanup() {
00109                 // When performing cleanup, we only do this once, but we can
00110                 // cope if somehow we have been called twice.
00111                 if (m_cleanupFn) 
00112             m_cleanupFn();
00113 
00114         // We need to remove "this" from the list
00115         // irregardless of the cleanup Function
00116         unregisterCleanup();
00117         }
00118 
00119         // This function is called during initialisation of static data to
00120         // register a function to be called on XMLPlatformUtils::Terminate.
00121         // It gives an object that uses static data an opportunity to reset
00122         // such data.
00123         void registerCleanup(XMLCleanupFn cleanupFn) {
00124                 // Store the cleanup function
00125                 m_cleanupFn = cleanupFn;
00126                 
00127                 // Add this object to the list head, if it is not already 
00128                 // present - which it shouldn't be.
00129                 // This is done under a mutex to ensure thread safety.
00130                 gXMLCleanupListMutex->lock();
00131                 if (!m_nextCleanup && !m_prevCleanup) {
00132                         m_nextCleanup = gXMLCleanupList;
00133                         gXMLCleanupList = this;
00134 
00135                         if (m_nextCleanup) 
00136                                 m_nextCleanup->m_prevCleanup = this;
00137                 }
00138                 gXMLCleanupListMutex->unlock();
00139         }
00140 
00141         // This function can be called either from XMLPlatformUtils::Terminate
00142         // to state that the cleanup has been performed and should not be
00143         // performed again, or from code that you have written that determines
00144         // that cleanup is no longer necessary.
00145         void unregisterCleanup() {
00146                 gXMLCleanupListMutex->lock();
00147 
00148         //
00149         // To protect against some compiler's (eg hp11) optimization
00150         // to change "this" as they update gXMLCleanupList
00151         //
00152         // refer to 
00153         // void XMLPlatformUtils::Terminate()
00154         //       ... 
00155         //       while (gXMLCleanupList)
00156                 //            gXMLCleanupList->doCleanup();
00157         //
00158 
00159         XMLRegisterCleanup *tmpThis = (XMLRegisterCleanup*) this;
00160 
00161         // Unlink this object from the cleanup list
00162                 if (m_nextCleanup) m_nextCleanup->m_prevCleanup = m_prevCleanup;
00163                 
00164                 if (!m_prevCleanup) gXMLCleanupList = m_nextCleanup;
00165                 else m_prevCleanup->m_nextCleanup = m_nextCleanup;
00166 
00167                 gXMLCleanupListMutex->unlock();
00168                 
00169                 // Reset the object to the default state
00170                 tmpThis->resetCleanup();
00171         }
00172 
00173         // The default constructor sets a state that ensures that this object
00174         // will do nothing
00175         XMLRegisterCleanup()
00176         {
00177                 resetCleanup();
00178         }
00179 
00180 private:
00181 
00182     //
00183     // unsupported ctor and operator
00184     //
00185         XMLRegisterCleanup(const XMLRegisterCleanup&)
00186         {}
00187 
00188         // This is the cleanup function to be called
00189         XMLCleanupFn m_cleanupFn;
00190 
00191         // These are list pointers to the next/prev cleanup function to be called
00192         XMLRegisterCleanup *m_nextCleanup, *m_prevCleanup;
00193 
00194         // This function reinitialises the object to the default state
00195         void resetCleanup() {
00196                 m_nextCleanup = 0;
00197                 m_prevCleanup = 0;
00198                 m_cleanupFn = 0;
00199         }
00200 };
00201 
00202 #endif

Generated on Tue Nov 19 09:36:35 2002 by doxygen1.3-rc1