Oracle Coherence for C++ API
Release 3.6.0.0

E15728-01

coherence/lang/WeakHandle.hpp

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