coherence/lang/SmartMember.hpp

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
Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.