Oracle Coherence for C++ API
Release 3.6.0.0
E15728-01

- Main Page
- Namespaces
- Classes
- Files

# coherence/lang/WeakHolder.hpp

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