Oracle® Fusion Middleware C++ API Reference for Oracle Coherence
12c (12.2.1.4.0)

E90870-01

coherence/lang/SmartMember.hpp

00001 /*
00002 * SmartMember.hpp
00003 *
00004 * Copyright (c) 2000, 2019, 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
Copyright © 2000, 2019, Oracle and/or its affiliates. All rights reserved.