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