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

E26041-01

coherence/lang/WeakHolder.hpp

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