coherence/lang/FinalizableBlock.hpp

00001 /*
00002 * FinalizableBlock.hpp
00003 *
00004 * Copyright 2001-2008 by Oracle. All rights reserved.
00005 *
00006 * Oracle is a registered trademarks of Oracle Corporation and/or its
00007 * affiliates.
00008 *
00009 * This software is the confidential and proprietary information of Oracle
00010 * Corporation. You shall not disclose such confidential and proprietary
00011 * information and shall use it only in accordance with the terms of the
00012 * license agreement you entered into with Oracle.
00013 *
00014 * This notice may not be removed or altered.
00015 */
00016 #ifndef COH_FINALIZABLE_BLOCK_HPP
00017 #define COH_FINALIZABLE_BLOCK_HPP
00018 
00019 #include <stddef.h>
00020 
00021 #include "coherence/lang/compatibility.hpp"
00022 
00023 COH_OPEN_NAMESPACE2(coherence,lang)
00024 
00025 
00026 /**
00027 * A finalizable block which runs a series of chained Finalizers as part of
00028 * its destruction.
00029 *
00030 * FinalizableBlocks are useful for cases where a series of finalization
00031 * routines need to be run from a nested function calls. For non-nested
00032 * finalization the use of a FinalizableBlock is unnecessary, and a disposable
00033 * or local class should be used.
00034 */
00035 class COH_EXPORT FinalizableBlock
00036     {
00037     // ----- constructors ---------------------------------------------------
00038 
00039     protected:
00040         /**
00041         * Construct a FinalizableBlock object.
00042         *
00043         * @param pDelegate  FinalizableBlock to delegate to, or NULL for
00044         *                   no delegate
00045         */
00046         FinalizableBlock(FinalizableBlock* pDelegate = NULL);
00047 
00048         /**
00049         * Copy constructor.
00050         *
00051         * The new block takes over the ownership of the finalization, the
00052         * supplied block is invalidated, and is not longer useable.
00053         *
00054         * @see COH_FINALIZABLE
00055         */
00056         FinalizableBlock(const FinalizableBlock& that);
00057 
00058         /**
00059         * Destroy a FinalizableBlock object.
00060         *
00061         * In the case of delegating blocks the destructor has no effect,
00062         * otherwise the finalizer stack is popped, until until all finalizers
00063         * have been deleted.
00064         */
00065         ~FinalizableBlock();
00066 
00067 
00068     // ----- operators ------------------------------------------------------
00069 
00070     public:
00071         /*
00072         * Boolean conversion for use in COH_FINALIZABLE macro.
00073         *
00074         * @return false always
00075         */
00076         operator bool() const;
00077 
00078     private:
00079         /**
00080         * Blocked assignement operator.
00081         */
00082         const FinalizableBlock& operator=(const FinalizableBlock&);
00083 
00084 
00085     // -------- nested class: Finalizer -------------------------------------
00086 
00087     public:
00088         /**
00089         * Interface for custom automatic cleanup operations.
00090         */
00091         class COH_EXPORT Finalizer
00092             {
00093             // ----- constructor/destrutor -----------------------------
00094 
00095             public:
00096                 /**
00097                 * Finalizer constructor.
00098                 */
00099                 Finalizer();
00100 
00101                 /**
00102                 * Finalizer destructor.
00103                 */
00104                 virtual ~Finalizer();
00105 
00106 
00107             // ----- data members --------------------------------------
00108 
00109             private:
00110                 /**
00111                 * Pointer to the next Finalizer on the stack.
00112                 */
00113                 Finalizer* m_pNext;
00114 
00115 
00116             // ----- friends -------------------------------------------
00117 
00118             friend class FinalizableBlock;
00119             };
00120 
00121 
00122     // ----- FinalizableBlock interface -------------------------------------
00123 
00124     public:
00125         /**
00126         * Push a custom finalizer onto the FinalizableBlock's
00127         * finalization stack.
00128         *
00129         * If the FinalizableBlock was constructed with a delegate,
00130         * then the finalizer is pushed on the delegates finalizer stack.
00131         *
00132         * The finalizer will then be owned by the FinalizableBlock and will
00133         * be automatically deleted with the top-most FinalizableBlock is
00134         * destroyed.
00135         *
00136         * @param pFinalizer  finalizer to add to the finalization stack
00137         */
00138         void pushFinalizer(Finalizer* pFinalizer);
00139 
00140     protected:
00141         /**
00142         * Return true if the FinalizableBlock is not delegating to
00143         * another FinalizableBlock.
00144         *
00145         * @return return true if the FinalizableBlock is not delegating
00146         *         to another FinalizableBlock
00147         */
00148         bool isTerminal() const;
00149 
00150         /**
00151         * Initialize a FinalizableBlock object.
00152         *
00153         * A block may be re-initialized so long as it has not been assigned a
00154         * delegate, and has no finalization stack.
00155         *
00156         * @param pDelegate  FinalizableBlock to delegate to, or NULL for
00157         *                   no delegate
00158         */
00159         void initialize(FinalizableBlock* pDelegate = NULL);
00160 
00161 
00162     // ----- data members ---------------------------------------------------
00163 
00164     private:
00165         /**
00166         * If non-NULL specified a FinalizableBlock to delegate to.
00167         */
00168         mutable FinalizableBlock* m_pDelegate;
00169 
00170         /**
00171         * The head of the finalizer stack.
00172         */
00173         mutable Finalizer* m_pFinalizerHead;
00174     };
00175 
00176 COH_CLOSE_NAMESPACE2
00177 
00178 /**
00179 * Macro for making more readable finalizable code blocks See the
00180 * documentation of FinalizableBlock for a useage example.
00181 *
00182 * The macro will create a well known FinalizableBlock instance referenceable
00183 * as "finally".
00184 *
00185 * @see coherence::lang::FinalizableBlock
00186 */
00187 #define COH_FINALIZABLE() \
00188     if (coherence::lang::FinalizableBlock finally \
00189         = coherence::lang::FinalizableBlock()) \
00190         { \
00191         COH_THROW(coherence::lang::IllegalStateException::create()); \
00192         } \
00193     else
00194 
00195 #endif // COH_FINALIZABLE_BLOCK_HPP
Copyright (c) 2000-2008 Oracle. All rights reserved.