csutil/weakreferenced.h
Go to the documentation of this file.00001 /* 00002 Crystal Space Weak Reference Counting Implementation 00003 Copyright (C) 2006 by Jorrit Tyberghein 00004 (C) 2006 by Amir Taaki 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License as published by the Free Software Foundation; either 00009 version 2 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public 00017 License along with this library; if not, write to the Free 00018 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00019 */ 00020 00021 #ifndef __CS_CSUTIL_WEAKREFERENCED_H__ 00022 #define __CS_CSUTIL_WEAKREFERENCED_H__ 00023 00028 #include "array.h" 00029 #include "refcount.h" 00030 00031 namespace CS 00032 { 00033 namespace Utility 00034 { 00035 namespace Implementation 00036 { 00041 class WeakReferenced 00042 { 00043 public: 00044 WeakReferenced() : weakref_owners (nullptr) {} 00045 ~WeakReferenced () 00046 { 00047 ClearRefOwners(); 00048 delete weakref_owners; 00049 } 00050 00051 void AddRefOwner (void** ref_owner, CS::Threading::Mutex* mutex) 00052 { 00053 if (!weakref_owners) 00054 weakref_owners = new WeakRefOwnerArray (0); 00055 weakref_owners->InsertSorted (WeakRefOwner (ref_owner, mutex)); 00056 } 00057 void RemoveRefOwner (void** ref_owner) 00058 { 00059 if (!weakref_owners) 00060 return; 00061 00062 size_t index = weakref_owners->FindSortedKey ( 00063 csArrayCmp<WeakRefOwner, void**>(ref_owner)); 00064 00065 if (index != csArrayItemNotFound) 00066 weakref_owners->DeleteIndex (index); 00067 } 00068 00070 void ClearRefOwners () 00071 { 00072 if (weakref_owners) 00073 { 00074 for (size_t i = 0; i < weakref_owners->GetSize(); i++) 00075 { 00076 const WeakRefOwner& wro ((*weakref_owners)[i]); 00077 void** p = wro.ownerObj; 00078 *p = nullptr; 00079 } 00080 } 00081 } 00082 00084 void DeleteAllOwners () 00085 { 00086 if (weakref_owners) 00087 { 00088 weakref_owners->DeleteAll (); 00089 } 00090 } 00091 00093 class ScopedWeakRefOwnersLock 00094 { 00095 WeakReferenced& object; 00096 public: 00097 ScopedWeakRefOwnersLock (WeakReferenced& object) : object (object) 00098 { 00099 if (object.weakref_owners) 00100 { 00101 for (size_t i = 0; i < object.weakref_owners->GetSize (); i++) 00102 { 00103 WeakRefOwner& wro ((*object.weakref_owners)[i]); 00104 if (wro.ownerObjMutex) wro.ownerObjMutex->Lock(); 00105 } 00106 } 00107 } 00108 ~ScopedWeakRefOwnersLock () 00109 { 00110 if (object.weakref_owners) 00111 { 00112 for (size_t i = 0; i < object.weakref_owners->GetSize (); i++) 00113 { 00114 WeakRefOwner& wro ((*object.weakref_owners)[i]); 00115 if (wro.ownerObjMutex) wro.ownerObjMutex->Unlock(); 00116 } 00117 } 00118 } 00119 }; 00120 00121 protected: 00122 struct WeakRefOwner 00123 { 00124 void** ownerObj; 00125 CS::Threading::Mutex* ownerObjMutex; 00126 00127 WeakRefOwner (void** p, CS::Threading::Mutex* mutex) 00128 : ownerObj (p), ownerObjMutex (mutex) {} 00129 00130 bool operator<(const WeakRefOwner& other) const 00131 { return ownerObj < other.ownerObj; } 00132 bool operator<(void** other) const 00133 { return ownerObj < other; } 00134 friend bool operator<(void** o1, const WeakRefOwner& o2) 00135 { return o1 < o2.ownerObj; } 00136 }; 00137 typedef csArray<WeakRefOwner, 00138 csArrayElementHandler<WeakRefOwner>, 00139 CS::Memory::AllocatorMalloc, 00140 csArrayCapacityLinear<csArrayThresholdFixed<4> > > WeakRefOwnerArray; 00141 WeakRefOwnerArray* weakref_owners; 00142 }; 00143 } 00144 00154 class WeakReferenced 00155 { 00156 public: 00157 void AddRefOwner (void** ref_owner, CS::Threading::Mutex* romutex) 00158 { 00159 impl.AddRefOwner (ref_owner, romutex); 00160 } 00161 void RemoveRefOwner (void** ref_owner) 00162 { 00163 impl.RemoveRefOwner (ref_owner); 00164 } 00165 00166 typedef WeakReferenced* WeakReferencedKeepAlive; 00167 private: 00168 Implementation::WeakReferenced impl; 00169 }; 00170 00171 } // namespace Utility 00172 } // namespace CS 00173 00174 #endif // __CS_CSUTIL_WEAKREFERENCED_H__
Generated for Crystal Space 2.1 by doxygen 1.6.1
