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

E90870-01

coherence/lang/WeakHolder.hpp

00001 /*
00002 * WeakHolder.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_WEAK_HOLDER_HPP
00017 #define COH_WEAK_HOLDER_HPP
00018 
00019 #include "coherence/lang/compatibility.hpp"
00020 
00021 #include "coherence/lang/Object.hpp"
00022 #include "coherence/lang/TypedHandle.hpp"
00023 #include "coherence/lang/TypedHolder.hpp"
00024 #include "coherence/lang/MemberHolder.hpp"
00025 #include "coherence/lang/WeakReference.hpp"
00026 
00027 #include <ostream>
00028 
00029 COH_OPEN_NAMESPACE2(coherence,lang)
00030 
00031 
00032 /**
00033 * WeakHolders are a TypedHolder like wrapper around WeakReferences.
00034 * WeakReferences allow one Object to safely reference another without blocking
00035 * it from being destroyed. WeakRefereces are necessary when building Object
00036 * graphs to avoid leaking the Object graph due to cyclical references.
00037 *
00038 * WeakReferences are automatically NULL'd out when their referenced Object
00039 * is destroyed. Additionally if the weakly referenced Object becomes only
00040 * referenced via Views, then the WeakReference and corresponding WeakHandle
00041 * will only return View to the Object, if an attempt is made to obtain a
00042 * Handle a NULL will be returned instead.
00043 *
00044 * WeakHolders are wrappers for MemberHolder, and provide a thread-safe handle
00045 * implementation.  As such they require references to both the referenced
00046 * "child" Object, as well as the owning "parent" Object. As with MemberHolder
00047 * the parent object must inherit from Object.
00048 *
00049 * Note: In the rare case that a WeakHolder is declared via the mutable
00050 *       keyword, the WeakHolder must be informed of this fact by setting
00051 *       fMutable to true during construction.
00052 *
00053 * @see MemberHolder
00054 *
00055 * @author mf  2008.12.09
00056 */
00057 template<class T>
00058 class WeakHolder
00059     {
00060     // ----- typedefs -------------------------------------------------------
00061 
00062     public:
00063         /**
00064         * The type of Object which this handle weakly references.
00065         */
00066         typedef const T ValueType;
00067 
00068         /**
00069         * The associated non-weak Handle type.
00070         */
00071         typedef typename T::Handle ValueHandle;
00072 
00073         /**
00074         * The associated non-weak View type.
00075         */
00076         typedef typename T::View ValueView;
00077 
00078         /**
00079         * The associated non-weak Holder type.
00080         */
00081         typedef typename T::Holder ValueHolder;
00082 
00083 
00084     // ----- constructors ---------------------------------------------------
00085 
00086     public:
00087         /**
00088         * Construct a WeakHolder referencing NULL.
00089         *
00090         * @param oGuardian  reference to the WeakHolder's parent
00091         */
00092         WeakHolder(const Object& oGuardian)
00093             : m_ohWeak(oGuardian, WeakReference::valueOf(NULL)),
00094               m_cpWeak(NULL)
00095             {
00096             }
00097 
00098         /**
00099         * Construct a WeakHolder referencing an object.
00100         *
00101         * @param oGuardian  reference to the WeakHolder's parent
00102         * @param that       the object to reference
00103         */
00104         WeakHolder(const Object& oGuardian, const TypedHolder<T>& that)
00105             : m_ohWeak(oGuardian, WeakReference::valueOf(that)),
00106               m_cpWeak(get_pointer(that))
00107             {
00108             }
00109 
00110         /**
00111         * Construct a WeakHolder referencing an object.
00112         *
00113         * @param oGuardian  reference to the WeakHolder's parent
00114         * @param that       the object to reference
00115         * @param fMutable   true if the member is declared as mutable, false
00116         *                   if declared as const
00117         */
00118         WeakHolder(const Object& oGuardian, const TypedHolder<T>& that,
00119                 bool fMutable)
00120             : m_ohWeak(oGuardian, WeakReference::valueOf(that), fMutable),
00121               m_cpWeak(get_pointer(that))
00122             {
00123             }
00124 
00125 
00126     // ----- operators ------------------------------------------------------
00127 
00128     public:
00129         /**
00130         * Re-assign the WeakHolder to weakly reference a new Object.
00131         *
00132         * @param that  the object to reference
00133         */
00134         WeakHolder& operator=(const TypedHolder<T>& that)
00135             {
00136             WeakReference::Holder ohRef  = WeakReference::valueOf(that);
00137             const T*              cpThat = get_pointer(that);
00138 
00139             // update m_ohWeak and m_cpWeak under a single write lock
00140                 {
00141                 SynchronizedMemberWriteBlock guard(get_guardian(m_ohWeak));
00142                 guard.setMember(m_ohWeak, ohRef);
00143                 m_cpWeak = cpThat;
00144                 }
00145 
00146             return *this;
00147             }
00148 
00149         /**
00150         * Re-assign the WeakHolder to weakly reference a new Object.
00151         *
00152         * @param that  the object to reference
00153         */
00154         WeakHolder& operator=(const WeakHolder& that)
00155             {
00156             return operator=((ValueHolder) that);
00157             }
00158 
00159         /**
00160         * Return a non-weak View to the weakly referenced Object, or a
00161         * View to NULL if the weakly referenced Object has been
00162         * destroyed.
00163         *
00164         * @return ValueView
00165         */
00166         operator ValueView() const
00167             {
00168             WeakReference::View vRef;
00169             const T*            cpWeak;
00170 
00171             // read m_ohWeak and m_cpWeak under a single read lock
00172                 {
00173                 SynchronizedMemberReadBlock guard(get_guardian(m_ohWeak));
00174                 vRef   = guard.getMember(m_ohWeak);
00175                 cpWeak = m_cpWeak;
00176                 }
00177 
00178             Object::View v = vRef->get();
00179             return NULL == v
00180                 ? TypedHandle<const T>() // Object has been collected
00181                 : TypedHandle<const T>(cpWeak, v);
00182             }
00183 
00184         /**
00185         * Return a View to the referenced Object.
00186         *
00187         * @return a View to the referenced Object
00188         */
00189         template<class PT>
00190         operator TypedHandle<const PT>() const
00191             {
00192             return (ValueView) *this;
00193             }
00194 
00195         /**
00196         * Return a TypedHolder to the referenced Object.
00197         *
00198         * @return a TypedHolder to the referenced Object
00199         */
00200         template<class PT>
00201         operator TypedHolder<PT>() const
00202             {
00203             WeakReference::Holder ohRef;
00204             const T*              cpWeak;
00205 
00206             // read m_hWeak and m_pWeak under a single read lock
00207                 {
00208                 SynchronizedMemberReadBlock guard(get_guardian(m_ohWeak));
00209                 ohRef  = guard.getMember(m_ohWeak);
00210                 cpWeak = m_cpWeak;
00211                 }
00212 
00213             WeakReference::Handle hRef = cast<WeakReference::Handle>(ohRef,
00214                     /*fThrow*/ false);
00215             Object::Holder        oh   = NULL == hRef
00216                 ? ohRef->get()
00217                 : hRef->get();
00218 
00219             if (NULL == oh)
00220                 {
00221                 return NULL; // Object has been collected
00222                 }
00223             else if (NULL == hRef)
00224                 {
00225                 return TypedHandle<const T>(cpWeak, oh); // View
00226                 }
00227             else
00228                 {
00229                 return TypedHandle<T>(const_cast<T*>(cpWeak), oh); // Handle
00230                 }
00231             }
00232 
00233         /**
00234         * Dereference the WeakHolder returning a non-weak View.
00235         *
00236         * If the non-weak View is non-NULL then it is guaranteed
00237         * that the Object will continue to exist for at least the
00238         * life of the returned View.
00239         *
00240         * @return a non-weak View to the referenced Object
00241         */
00242         ValueView operator->() const
00243             {
00244             return (ValueView) *this;
00245             }
00246 
00247         /**
00248         * Dereference this handle, returning <tt>T&</tt>.
00249         *
00250         * @return a raw <tt>T&</tt> reference to the referenced Object
00251         *
00252         * @throws NullPointerException if the this handle is @c NULL
00253         */
00254         const T& operator*() const
00255             {
00256             return *operator->();
00257             }
00258 
00259     // ----- data members ---------------------------------------------------
00260 
00261     protected:
00262         /**
00263         * The Holder to the associated WeakReference.
00264         */
00265         MemberHolder<WeakReference> m_ohWeak;
00266 
00267         /**
00268         * Raw pointer to the weakly referenced object.
00269         */
00270         const T* m_cpWeak;
00271     };
00272 
00273 
00274 // ----- non-member operators and functions ---------------------------------
00275 
00276 /**
00277 * Output a human-readable description of the given
00278 * WeakHolder<T> to the specified stream.
00279 *
00280 * @param out  the stream used to output the description
00281 * @param woh   the WeakHolder<T> to describe
00282 *
00283 * @return the supplied stream
00284 */
00285 template <typename Char, typename Traits, class T>
00286 COH_INLINE std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& out, const WeakHolder<T>& woh)
00287     {
00288     typename WeakHolder<T>::ValueView v = woh;
00289     out << v;
00290     return out;
00291     }
00292 
00293 /**
00294 * Assign the specified handle to NULL.
00295 *
00296 * @param woh the handle to clear
00297 */
00298 template<class T> void clear_handle(WeakHolder<T>& woh)
00299     {
00300     woh = NULL;
00301     }
00302 
00303 /**
00304 * Return true if the supplied handle equals NULL.
00305 *
00306 * @param woh  the weak handle to test
00307 *
00308 * @return true iff the supplied handle equals NULL
00309 */
00310 template<class T>
00311 bool is_null(const WeakHolder<T>& woh)
00312     {
00313     return woh == NULL;
00314     }
00315 
00316 /**
00317 * Perform a dynamic cast the pointer associated with the WeakHolder
00318 * to a the specified handle/view type.
00319 *
00320 * @param woh      the WeakHolder from which to perform the cast
00321 * @param fThrow   true if an exception is to be thrown on a failed cast
00322 *
00323 * @return the casted pointer, or NULL if the cast fails and fThrow is false
00324 *
00325 * @throws ClassCastException if the cast fails and fThrow is true
00326 */
00327 template<class D, class T>
00328 D cast(const WeakHolder<T>& woh, bool fThrow = true)
00329     {
00330     return cast<D>((TypedHolder<T>) woh, fThrow);
00331     }
00332 
00333 /**
00334 * Perform an instanceof check on a handle or view.
00335 *
00336 * @param woh  the WeakHolder from which to perform the test
00337 *
00338 * @return true if the supplied handle is an instance of the specified type
00339 */
00340 template<class D, class T>
00341 bool instanceof(const WeakHolder<T>& woh)
00342     {
00343     return NULL != cast<D>(woh, false);
00344     }
00345 
00346 COH_CLOSE_NAMESPACE2
00347 
00348 #endif // COH_WEAK_HOLDER_HPP
Copyright © 2000, 2019, Oracle and/or its affiliates. All rights reserved.