00001 /* 00002 * SmartMember.hpp 00003 * 00004 * Copyright (c) 2000, 2009, Oracle and/or its affiliates. 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_SMART_MEMBER_HPP 00017 #define COH_SMART_MEMBER_HPP 00018 00019 #include "coherence/lang/compatibility.hpp" 00020 00021 #include "coherence/lang/Object.hpp" 00022 00023 COH_OPEN_NAMESPACE2(coherence,lang) 00024 00025 00026 /** 00027 * Base class for smart data-members of managed Objects. 00028 * 00029 * Smart data-members include additional information regarding their 00030 * life-cycle, including a reference to their enclosing Object (guardian). The 00031 * smart member is initialized with a reference to its guardian, and has the 00032 * same life-cycle as the guardian. Creating a SmartMember which is not a 00033 * data-member of the guardian used during initialization will result in 00034 * unsafe/undefined behavior. 00035 * 00036 * @author mf 2008.01.30 00037 */ 00038 class COH_EXPORT SmartMember 00039 { 00040 // ----- nested type: Mutability ---------------------------------------- 00041 00042 public: 00043 /** 00044 * The mutability of the SmartMember. 00045 */ 00046 typedef enum 00047 { 00048 INHERITED = 0, // matches parent 00049 MUTABLE = 1, // forever mutable 00050 CONST = 2, // no longer mutable; can't go back 00051 SAFE_CONST = 3 // not mutable, and reads don't need synchronization 00052 } Mutability; 00053 00054 00055 // ----- constructor ---------------------------------------------------- 00056 00057 public: 00058 /** 00059 * Construct a new SmartMember 00060 * 00061 * @param oGuardian the data-member's guardian Object. 00062 * @param nMutability the mutability of the SmartMember 00063 */ 00064 SmartMember(const Object& oGuardian, Mutability nMutability = INHERITED) 00065 : m_nMutability(nMutability) 00066 { 00067 if (oGuardian._isEscaped()) 00068 { 00069 m_pGuardian = NULL; 00070 setGuardian(oGuardian); 00071 } 00072 else 00073 { 00074 m_pGuardian = &oGuardian; 00075 m_pNext = oGuardian.m_pSmartMemberStack; 00076 oGuardian.m_pSmartMemberStack = this; 00077 } 00078 } 00079 00080 00081 /** 00082 * Destruct the SmartMember. 00083 */ 00084 virtual ~SmartMember() 00085 { 00086 Object const* pGuardian = m_pGuardian; 00087 if (NULL != pGuardian && !pGuardian->_isEscaped() && 00088 this == pGuardian->m_pSmartMemberStack) 00089 { 00090 // we are at the top of the stack 00091 pGuardian->m_pSmartMemberStack = m_pNext; 00092 } 00093 else 00094 { 00095 unlinkGuardian(); 00096 } 00097 } 00098 00099 protected: 00100 /** 00101 * Construct an orphaned SmartMember. 00102 * 00103 * The smart-member will not be usable until a guardian is assigned. 00104 * 00105 * @see #setGuardian() 00106 */ 00107 SmartMember(); 00108 00109 private: 00110 /** 00111 * Blocked copy constructor. 00112 */ 00113 SmartMember(const SmartMember&); 00114 00115 00116 // ----- operators ------------------------------------------------------ 00117 00118 public: 00119 SmartMember& operator=(const SmartMember& that); 00120 00121 00122 // ----- SmartMember interface ------------------------------------------ 00123 00124 protected: 00125 /** 00126 * @internal 00127 * 00128 * Return the guardian Object for this data member. 00129 * 00130 * @return the guardian Object for this data member. 00131 */ 00132 const Object& getGuardian() const 00133 { 00134 return *m_pGuardian; 00135 } 00136 00137 /** 00138 * @internal 00139 * 00140 * Set the guardian for this member. 00141 * 00142 * This method is not thread-safe and should not be called on an 00143 * escaped object. 00144 */ 00145 void setGuardian(const Object& oGuardian); 00146 00147 /** 00148 * @internal 00149 * 00150 * Removes this SmartMember from its guardian. 00151 */ 00152 void unlinkGuardian(); 00153 00154 00155 // ----- life cycle events ---------------------------------------------- 00156 00157 protected: 00158 /** 00159 * Event called once the guardian Object has finished being constructed. 00160 * Specifically when the first attachment is made. 00161 * 00162 * As with all event methods any derived implementation should 00163 * include a call to the super class's implementation. 00164 * 00165 * The default implementation calls the onInit() method of each of the 00166 * Object's SmartMembers. 00167 */ 00168 virtual void onInit() 00169 { 00170 } 00171 00172 /** 00173 * Event called when the guardian Object becomes only referenced via 00174 * const pointers (Views). As the SmartMember is a data-member 00175 * of this Object, the data-member infer that only const methods will 00176 * be called from now on. 00177 * 00178 * Derived implementations of this method should include a delegation 00179 * call to their super class onConst() method, after they've done 00180 * their own processing of the event. 00181 * 00182 * Not that this method will only be called by the guardian if the 00183 * SmartMember's mutability state is set to INHERITED. 00184 */ 00185 virtual void onConst() 00186 { 00187 m_nMutability = CONST; 00188 } 00189 00190 /** 00191 * Event called when the guarding Object's escape state changes. 00192 * 00193 * Derived implementations of this method should include a delegation 00194 * call to their super class onEscape() method, after they've done 00195 * their own processing of the event. 00196 * 00197 * @param fEscaped true if the object is being escaped, false if the 00198 * object is being captured 00199 */ 00200 virtual void onEscape(bool /*fEscaped*/) const 00201 { 00202 if (m_nMutability == CONST) 00203 { 00204 // CONST cannot go back to mutable, and we are single threaded 00205 // at this point any associated "const" value can be safely 00206 // read without the need for synchronization 00207 m_nMutability = SAFE_CONST; 00208 } 00209 } 00210 00211 00212 // ----- data members --------------------------------------------------- 00213 00214 protected: 00215 /** 00216 * The mutability of the SmartMember. 00217 */ 00218 mutable Mutability m_nMutability; 00219 00220 private: 00221 /** 00222 * The Member's guardian. 00223 */ 00224 Object const* m_pGuardian; 00225 00226 /** 00227 * The next SmartMember in the guardian's SmartMember stack. 00228 */ 00229 mutable SmartMember* m_pNext; 00230 00231 00232 // ----- friends -------------------------------------------------------- 00233 00234 friend class Object; 00235 00236 friend const Object& get_guardian(const SmartMember& member); 00237 }; 00238 00239 /** 00240 * @internal 00241 * 00242 * Return the guardian Object for the smart member. 00243 * 00244 * @return the guardian Object for the smart member. 00245 */ 00246 inline const Object& get_guardian(const SmartMember& member) 00247 { 00248 return member.getGuardian(); 00249 } 00250 00251 COH_CLOSE_NAMESPACE2 00252 00253 #endif // COH_SMART_MEMBER_HPP