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