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