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

E80355-01

coherence/lang/WeakHandle.hpp

00001 /*
00002 * WeakHandle.hpp
00003 *
00004 * Copyright (c) 2000, 2017, 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_HANDLE_HPP
00017 #define COH_WEAK_HANDLE_HPP
00018 
00019 #include "coherence/lang/compatibility.hpp"
00020 
00021 #include "coherence/lang/MemberHandle.hpp"
00022 #include "coherence/lang/Object.hpp"
00023 #include "coherence/lang/TypedHandle.hpp"
00024 #include "coherence/lang/TypedHolder.hpp"
00025 #include "coherence/lang/WeakReference.hpp"
00026 
00027 #include <ostream>
00028 
00029 COH_OPEN_NAMESPACE2(coherence,lang)
00030 
00031 
00032 /**
00033 * WeakHandles are a TypedHandle like wrapper around WeakReferences.
00034 * WeakReferences allow one Object to safely reference another without blocking
00035 * it from being destroyed. WeakReferences are necessary when building Object
00036 * graphs to avoid leaking the Object graph due to cyclic 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 * WeakHandles behave like MemberHandles by transferring their constness to
00045 * their referenced Object. As with MemberHandle WeakHandles are a thread-safe
00046 * handle implementation.  As such they require references to both the
00047 * referenced "child" Object, as well as the owning "parent" Object. As with
00048 * MemberView the parent object must inherit from Object.
00049 *
00050 * If the weakly referenced Object will always be referenced as a View then
00051 * using the WeakView class would be more appropriate
00052 *
00053 * Note: In the rare case that a WeakHandle is declared via the mutable
00054 *       keyword, the WeakHandle must be informed of this fact by setting
00055 *       fMutable to true during construction.
00056 *
00057 * @see MemberHandle
00058 * @see WeakView
00059 *
00060 * @author mf  2007.07.05
00061 */
00062 template<class T>
00063 class WeakHandle
00064     {
00065     // ----- typedefs -------------------------------------------------------
00066 
00067     public:
00068         /**
00069         * The type of Object which this handle weakly references.
00070         */
00071         typedef T ValueType;
00072 
00073         /**
00074         * The associated non-weak Handle type.
00075         */
00076         typedef typename T::Handle ValueHandle;
00077 
00078         /**
00079         * The associated non-weak View type.
00080         */
00081         typedef typename T::View ValueView;
00082 
00083         /**
00084         * The MemberHandle used to hold the internal WeakReference.
00085         */
00086         typedef MemberHandle<WeakReference> InnerHandle;
00087 
00088         /**
00089         * Result type for a non-const get operation.
00090         */
00091         typedef ValueHandle GetType;
00092 
00093         /**
00094         * Result type for a non-const get operation.
00095         */
00096         typedef ValueView ConstGetType;
00097 
00098 
00099     // ----- constructors ---------------------------------------------------
00100 
00101     public:
00102         /**
00103         * Default constructor.
00104         */
00105         WeakHandle(const Object& oGuardian)
00106             : m_hWeak(oGuardian), m_pWeak(NULL)
00107             {
00108             }
00109 
00110         /**
00111         * Construct a WeakHandle from a normal Handle.
00112         *
00113         * @param oGuardian  the self() on the object this data member is a
00114         *                   member of
00115         * @param that       the object to reference
00116         */
00117         WeakHandle(const Object& oGuardian, const TypedHandle<T>& that)
00118             : m_hWeak(oGuardian, NULL == that ? NULL : that->_attachWeak()),
00119               m_pWeak(get_pointer(that))
00120             {
00121             }
00122 
00123         /**
00124         * Construct a WeakHandle from a normal Handle.
00125         *
00126         * @param oGuardian  the self() on the object this data member is a
00127         *                   member of
00128         * @param that       the object to reference
00129         * @param fMutable   true if the member is declared as mutable, false
00130         *                   if declared as const
00131         */
00132         WeakHandle(const Object& oGuardian, const TypedHandle<T>& that, bool fMutable)
00133             : m_hWeak(oGuardian, NULL == that ? NULL : that->_attachWeak(),
00134                     fMutable),
00135               m_pWeak(get_pointer(that))
00136             {
00137             }
00138 
00139     private:
00140         /**
00141         * Blocked copy constructor.
00142         */
00143         WeakHandle(const WeakHandle& wh);
00144 
00145 
00146     // ----- operators ------------------------------------------------------
00147 
00148     public:
00149         /**
00150         * Re-assign the WeakHandle to weakly reference a new Object.
00151         *
00152         * @param that  the object to reference
00153         */
00154         WeakHandle& operator=(const TypedHandle<T>& that)
00155             {
00156             T*                    pThat = get_pointer(that);
00157             WeakReference::Handle hRef  = NULL == that
00158                 ? WeakReference::Handle(NULL)
00159                 : that->_attachWeak();
00160 
00161             // update m_hWeak and m_pWeak under a single write lock
00162                 {
00163                 SynchronizedMemberWriteBlock guard(get_guardian(m_hWeak));
00164                 guard.setMember(m_hWeak, hRef);
00165                 m_pWeak = pThat;
00166                 }
00167 
00168             return *this;
00169             }
00170 
00171         /**
00172         * Assign this WeakHandle to reference the same Object as the specified
00173         * WeakHandle.
00174         *
00175         * @param that  the object to reference
00176         *
00177         * @return a reference to this MemberHandle
00178         */
00179         WeakHandle& operator=(WeakHandle& that)
00180             {
00181             return operator=((ValueHandle) that); // assign from snapshot
00182             }
00183 
00184         /**
00185         * Return a non-weak Handle to the weakly referenced Object, or a
00186         * Handle to NULL if the weakly referenced Object has been destroyed
00187         * or is now only referenced via Views.
00188         *
00189         * @return ValueHandle
00190         */
00191         operator ValueHandle()
00192             {
00193             WeakReference::Handle hRef;
00194             T*                    pWeak;
00195 
00196             // read m_hWeak and m_pWeak under a single read lock
00197                 {
00198                 SynchronizedMemberReadBlock guard(get_guardian(m_hWeak));
00199                 hRef  = guard.getMember(m_hWeak);
00200                 pWeak = m_pWeak;
00201                 }
00202 
00203             if (NULL == hRef)
00204                 {
00205                 return NULL;
00206                 }
00207 
00208             // utilize pWeak to avoid cost of dynamic cast
00209             Object::Handle h = cast<Object::Handle>(hRef->get(),
00210                     /*fThrow*/ false);
00211             return NULL == h
00212                 ? TypedHandle<T>()
00213                 : TypedHandle<T>(pWeak, h);
00214             }
00215 
00216         /**
00217         * Return a non-weak View to the weakly referenced Object, or a
00218         * Handle to NULL if the weakly referenced Object has been
00219         * destroyed.
00220         *
00221         * @return ValueHandle
00222         */
00223         operator ValueView() const
00224             {
00225             WeakReference::View vRef;
00226             const T*            cpWeak;
00227 
00228             // read m_hWeak and m_pWeak under a single read lock
00229                 {
00230                 SynchronizedMemberReadBlock guard(get_guardian(m_hWeak));
00231                 vRef   = guard.getMember(m_hWeak);
00232                 cpWeak = m_pWeak;
00233                 }
00234 
00235             if (NULL == vRef)
00236                 {
00237                 return NULL;
00238                 }
00239 
00240             // utilize cpWeak to avoid cost of dynamic cast
00241             Object::View v = vRef->get();
00242             return NULL == v
00243                 ? TypedHandle<const T>()
00244                 : TypedHandle<const T>(cpWeak, v);
00245             }
00246 
00247         /**
00248         * Return a View to the referenced Object.
00249         *
00250         * @return a View to the referenced Object
00251         */
00252         template<class PT>
00253         operator TypedHandle<const PT>() const
00254             {
00255             return (ValueView) *this;
00256             }
00257 
00258         /**
00259         * Return a Handle to the referenced Object.
00260         *
00261         * @return a Handle to the referenced Object
00262         */
00263         template<class PT>
00264         operator TypedHandle<PT>()
00265             {
00266             return (ValueHandle) *this;
00267             }
00268 
00269         /**
00270         * Return a TypedHolder to the referenced Object.
00271         *
00272         * @return a TypedHolder to the referenced Object
00273         *
00274         */
00275         template<class PT>
00276         operator TypedHolder<PT>() const
00277             {
00278             return (ValueView) *this;
00279             }
00280 
00281         /**
00282         * Return a TypedHolder to the referenced Object.
00283         *
00284         * @return a TypedHolder to the referenced Object
00285         */
00286         template<class PT>
00287         operator TypedHolder<PT>()
00288             {
00289             return (ValueHandle) *this;
00290             }
00291 
00292         /**
00293         * Dereference the WeakHandle returning a non-weak Handle.
00294         *
00295         * If the non-weak Handle is non-NULL then it is guaranteed
00296         * that the Object will continue to exist for at least the
00297         * life of the returned handle.
00298         *
00299         * @return ValueHandle
00300         */
00301         ValueHandle operator->()
00302             {
00303             return (ValueHandle) *this;
00304             }
00305 
00306         /**
00307         * Dereference the WeakHandle returning a non-weak View.
00308         *
00309         * If the non-weak Handle is non-NULL then it is guaranteed
00310         * that the Object will continue to exist for at least the
00311         * life of the returned View.
00312         *
00313         * @return ValueHandle
00314         */
00315         ValueView operator->() const
00316             {
00317             return (ValueView) *this;
00318             }
00319 
00320         /**
00321         * Dereference this handle, returning <tt>T&</tt>.
00322         *
00323         * @return a raw <tt>T&</tt> reference to the referenced Object
00324         *
00325         * @throws NullPointerException if the this handle is @c NULL
00326         */
00327         const T& operator*() const
00328             {
00329             return *operator->();
00330             }
00331 
00332         /**
00333         * Dereference this handle, returning <tt>T&</tt>.
00334         *
00335         * @return a raw <tt>T&</tt> reference to the referenced Object
00336         *
00337         * @throws NullPointerException if the this handle is @c NULL
00338         */
00339         T& operator*()
00340             {
00341             return *operator->();
00342             }
00343 
00344     private:
00345         /**
00346         * Blocked assignment operator.
00347         */
00348         WeakHandle<T>& operator=(const WeakHandle<T>&);
00349 
00350 
00351     // ----- data members ---------------------------------------------------
00352 
00353     protected:
00354         /**
00355         * The Handle to the associated WeakReference.
00356         */
00357         InnerHandle m_hWeak;
00358 
00359         /**
00360         * Raw pointer to the weakly referenced object.
00361         */
00362         T* m_pWeak;
00363     };
00364 
00365 
00366 // ----- non-member operators and functions ---------------------------------
00367 
00368 /**
00369 * Output a human-readable description of the given WeakHandle<T> to the
00370 * specified stream.
00371 *
00372 * @param out  the stream used to output the description
00373 * @param wh   the WeakHandle<T> to describe
00374 *
00375 * @return the supplied stream
00376 */
00377 template <typename Char, typename Traits, class T>
00378 COH_INLINE std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& out, const WeakHandle<T>& wh)
00379     {
00380     typename WeakHandle<T>::ValueView v = wh;
00381     out << v;
00382     return out;
00383     }
00384 
00385 /**
00386 * Assign the specified handle to NULL.
00387 *
00388 * @param wh the handle to clear
00389 */
00390 template<class T> void clear_handle(WeakHandle<T>& wh)
00391     {
00392     wh = NULL;
00393     }
00394 
00395 /**
00396 * Return true if the supplied handle equals NULL.
00397 *
00398 * @param wh  the weak handle to test
00399 *
00400 * @return true iff the supplied handle equals NULL
00401 */
00402 template<class T>
00403 bool is_null(const WeakHandle<T>& wh)
00404     {
00405     return wh == NULL;
00406     }
00407 
00408 /**
00409 * Perform a dynamic cast the pointer associated with the WeakHandle
00410 * to a the specified handle/view type.
00411 *
00412 * @param wh     the WeakHandle from which to perform the cast
00413 * @param fTest  true for instanceof style test
00414 *
00415 * @return the casted pointer, or NULL if the cast fails and fTest is true
00416 *
00417 * @throws ClassCastException if the cast fails and fTest of is false
00418 */
00419 template<class D, class T>
00420 D cast(WeakHandle<T>& wh, bool fTest = false)
00421     {
00422     return cast<D>((typename WeakHandle<T>::ValueHandle) wh, fTest);
00423     }
00424 
00425 /**
00426 * Perform a dynamic cast the pointer associated with the WeakHandle
00427 * to a the specified handle/view type.
00428 *
00429 * @param wh      the WeakHandle from which to perform the cast
00430 * @param fThrow  true if an exception is to be thrown on a failed cast
00431 *
00432 * @return the casted pointer, or NULL if the cast fails and fThrow is false
00433 *
00434 * @throws ClassCastException if the cast fails and fThrow is true
00435 */
00436 template<class D, class T>
00437 D cast(const WeakHandle<T>& wh, bool fThrow = true)
00438     {
00439     return cast<D>((typename WeakHandle<T>::ValueHandle) wh, fThrow);
00440     }
00441 
00442 /**
00443 * Perform an instanceof check on a handle or view.
00444 *
00445 * @param wh  the WeakHandle from which to perform the test
00446 *
00447 * @return true if the supplied handle is an instance of the specified type
00448 */
00449 template<class D, class T>
00450 bool instanceof(const WeakHandle<T>& wh)
00451     {
00452     return NULL != cast<D>(wh, false);
00453     }
00454 
00455 /**
00456 * Perform an instanceof check on a handle or view.
00457 *
00458 * @param wh  the WeakHandle from which to perform the test
00459 *
00460 * @return true if the supplied handle is an instance of the specified type
00461 */
00462 template<class D, class T>
00463 bool instanceof(WeakHandle<T>& wh)
00464     {
00465     return NULL != cast<D>(wh, false);
00466     }
00467 
00468 COH_CLOSE_NAMESPACE2
00469 
00470 #endif // COH_WEAK_HANDLE_HPP
Copyright © 2000, 2017, Oracle and/or its affiliates. All rights reserved.