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