00001 /* 00002 * SmartMember.hpp 00003 * 00004 * Copyright (c) 2000, 2020, 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 * Return the deep byte size of any managed objects held by this 00157 * SmartMember. 00158 */ 00159 virtual size64_t retained() const = 0; 00160 00161 /** 00162 * Cross the guardian's read barrier. 00163 */ 00164 void readBarrier() const 00165 { 00166 getGuardian()._readBarrier(); 00167 } 00168 00169 /** 00170 * Cross the guardian's write barrier. 00171 */ 00172 void writeBarrier() const 00173 { 00174 getGuardian()._writeBarrier(); 00175 } 00176 00177 // ----- life cycle events ---------------------------------------------- 00178 00179 protected: 00180 /** 00181 * Event called once the guardian Object has finished being constructed. 00182 * Specifically when the first attachment is made. 00183 * 00184 * As with all event methods any derived implementation should 00185 * include a call to the super class's implementation. 00186 * 00187 * The default implementation calls the onInit() method of each of the 00188 * Object's SmartMembers. 00189 */ 00190 virtual void onInit() 00191 { 00192 } 00193 00194 /** 00195 * Event called when the guardian Object becomes only referenced via 00196 * const pointers (Views). As the SmartMember is a data-member 00197 * of this Object, the data-member infer that only const methods will 00198 * be called from now on. 00199 * 00200 * Derived implementations of this method should include a delegation 00201 * call to their super class onConst() method, after they've done 00202 * their own processing of the event. 00203 * 00204 * Not that this method will only be called by the guardian if the 00205 * SmartMember's mutability state is set to inherited. 00206 */ 00207 virtual void onConst() 00208 { 00209 m_nMutability = forever_immutable; 00210 } 00211 00212 /** 00213 * Event called when the guarding Object's escape state changes. 00214 * 00215 * Derived implementations of this method should include a delegation 00216 * call to their super class onEscape() method, after they've done 00217 * their own processing of the event. 00218 * 00219 * @param fEscaped true if the object is being escaped, false if the 00220 * object is being captured 00221 */ 00222 virtual void onEscape(bool /*fEscaped*/) const 00223 { 00224 if (m_nMutability == forever_immutable) 00225 { 00226 // forever_immutable cannot go back to mutable, and we are single threaded 00227 // at this point any associated "const" value can be safely 00228 // read without the need for synchronization 00229 m_nMutability = safe_immutable; 00230 } 00231 } 00232 00233 00234 // ----- data members --------------------------------------------------- 00235 00236 protected: 00237 /** 00238 * The mutability of the SmartMember. 00239 */ 00240 mutable Mutability m_nMutability; 00241 00242 private: 00243 /** 00244 * The Member's guardian. 00245 */ 00246 Object const* m_pGuardian; 00247 00248 /** 00249 * The next SmartMember in the guardian's SmartMember stack. 00250 */ 00251 mutable SmartMember* m_pNext; 00252 00253 00254 // ----- friends -------------------------------------------------------- 00255 00256 friend class Object; 00257 00258 friend const Object& get_guardian(const SmartMember& member); 00259 }; 00260 00261 /** 00262 * @internal 00263 * 00264 * Return the guardian Object for the smart member. 00265 * 00266 * @return the guardian Object for the smart member. 00267 */ 00268 inline const Object& get_guardian(const SmartMember& member) 00269 { 00270 return member.getGuardian(); 00271 } 00272 00273 COH_CLOSE_NAMESPACE2 00274 00275 #endif // COH_SMART_MEMBER_HPP