File indexing completed on 2024-04-21 15:38:21
0001 /* This file is part of the KDE project 0002 * 0003 * Copyright (C) 2004 Koos Vriezen <koos.vriezen@xs4all.nl> 0004 * 0005 * This library is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU Library General Public 0007 * License as published by the Free Software Foundation; either 0008 * version 2 of the License, or (at your option) any later version. 0009 * 0010 * This library is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 * Library General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU Library General Public License 0016 * along with this library; see the file COPYING.LIB. If not, write to 0017 * the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 * 0020 * until boost gets common, a more or less compatable one .. 0021 */ 0022 0023 #ifndef _SHAREDPTR_H_ 0024 #define _SHAREDPTR_H_ 0025 0026 //#define SHAREDPTR_DEBUG 0027 0028 #ifdef SHAREDPTR_DEBUG 0029 extern int shared_data_count; 0030 #include <iostream> 0031 #endif 0032 0033 #include "kmplayer_def.h" 0034 0035 namespace KMPlayer { 0036 0037 class KMPLAYER_EXPORT CacheAllocator { 0038 void **pool; 0039 size_t size; 0040 int count; 0041 public: 0042 CacheAllocator (size_t s); 0043 0044 void *alloc (); 0045 void dealloc (void *p); 0046 }; 0047 0048 extern CacheAllocator *shared_data_cache_allocator; 0049 0050 /** 0051 * Shared data for SharedPtr and WeakPtr objects. 0052 **/ 0053 template <class T> 0054 struct SharedData { 0055 SharedData (T * t, bool w) : use_count (w?0:1), weak_count (1), ptr (t) { 0056 #ifdef SHAREDPTR_DEBUG 0057 std::cerr << "SharedData::SharedData use:" << use_count << " weak:" << weak_count << " total:" << ++shared_data_count << std::endl; 0058 #endif 0059 } 0060 #ifdef SHAREDPTR_DEBUG 0061 ~SharedData () { std::cerr << "SharedData::~SharedData" << " total:" << --shared_data_count << std::endl; } 0062 #endif 0063 static void *operator new (size_t); 0064 static void operator delete (void *); 0065 void addRef (); 0066 void addWeakRef (); 0067 void release (); 0068 void releaseWeak (); 0069 void dispose (); 0070 int use_count; 0071 int weak_count; 0072 T * ptr; 0073 }; 0074 0075 template <class T> inline void *SharedData<T>::operator new (size_t s) { 0076 if (!shared_data_cache_allocator) 0077 shared_data_cache_allocator = new CacheAllocator (s); 0078 return shared_data_cache_allocator->alloc (); 0079 } 0080 0081 template <class T> inline void SharedData<T>::operator delete (void *p) { 0082 shared_data_cache_allocator->dealloc (p); 0083 } 0084 0085 template <class T> inline void SharedData<T>::addRef () { 0086 use_count++; 0087 weak_count++; 0088 #ifdef SHAREDPTR_DEBUG 0089 std::cerr << "SharedData::addRef use:" << use_count << " weak:" << weak_count << std::endl; 0090 #endif 0091 } 0092 0093 template <class T> inline void SharedData<T>::addWeakRef () { 0094 weak_count++; 0095 #ifdef SHAREDPTR_DEBUG 0096 std::cerr << "SharedData::addWeakRef use:" << use_count << " weak:" << weak_count << std::endl; 0097 #endif 0098 } 0099 0100 template <class T> inline void SharedData<T>::releaseWeak () { 0101 ASSERT (weak_count > 0 && weak_count > use_count); 0102 #ifdef SHAREDPTR_DEBUG 0103 std::cerr << "SharedData::releaseWeak use:" << use_count << " weak:" << weak_count-1 << std::endl; 0104 #endif 0105 if (--weak_count <= 0) delete this; 0106 } 0107 0108 template <class T> inline void SharedData<T>::release () { 0109 ASSERT (use_count > 0); 0110 if (--use_count <= 0) dispose (); 0111 #ifdef SHAREDPTR_DEBUG 0112 std::cerr << "SharedData::release use:" << use_count << " weak:" << weak_count << std::endl; 0113 #endif 0114 releaseWeak (); 0115 } 0116 0117 template <class T> inline void SharedData<T>::dispose () { 0118 ASSERT (use_count == 0); 0119 #ifdef SHAREDPTR_DEBUG 0120 std::cerr << "SharedData::dispose use:" << use_count << " weak:" << weak_count << std::endl; 0121 #endif 0122 T *p = ptr; 0123 ptr = NULL; 0124 delete p; 0125 } 0126 0127 template <class T> struct WeakPtr; 0128 0129 /** 0130 * Shared class based on boost shared 0131 * This makes it possible to share pointers w/o having to worry about 0132 * memory leaks. A pointer gets deleted as soon as the last Shared pointer 0133 * gets destroyed. As such, never use (or be extremely carefull) not to 0134 * use pointers or references to shared objects 0135 **/ 0136 template <class T> 0137 struct SharedPtr { 0138 SharedPtr () : data (0L) {}; 0139 SharedPtr (T *t) : data (t ? new SharedData<T> (t, false) : 0L) {} 0140 SharedPtr (const SharedPtr<T> & s) : data (s.data) { if (data) data->addRef (); } 0141 SharedPtr (const WeakPtr <T> &); 0142 ~SharedPtr () { if (data) data->release (); } 0143 SharedPtr<T> & operator = (const SharedPtr<T> &); 0144 SharedPtr<T> & operator = (const WeakPtr<T> &); 0145 SharedPtr<T> & operator = (T *); 0146 T * ptr () const { return data ? data->ptr : 0L; } 0147 T * operator -> () { return data ? data->ptr : 0L; } 0148 T * operator -> () const { return data ? data->ptr : 0L; } 0149 T & operator * () { return *data->ptr; } 0150 const T & operator * () const { return *data->ptr; } 0151 // operator bool () const { return data && data->ptr; } 0152 bool operator == (const SharedPtr<T> & s) const { return data == s.data; } 0153 bool operator == (const WeakPtr<T> & w) const; 0154 bool operator == (const T * t) const { return (!t && !data) || (data && data->ptr == t); } 0155 bool operator == (T * t) const { return (!t && !data) || (data && data->ptr == t); } 0156 bool operator != (const SharedPtr<T> & s) const { return data != s.data; } 0157 bool operator != (const WeakPtr<T> & w) const; 0158 bool operator != (const T * t) const { return !operator == (t); } 0159 operator T * () { return data ? data->ptr : 0L; } 0160 operator const T * () const { return data ? data->ptr : 0L; } 0161 mutable SharedData<T> * data; 0162 }; 0163 0164 template <class T> 0165 bool operator == (T * t, SharedPtr <T> & s) { 0166 return (!t && !s.data) || (s.data && s.data->ptr == t); 0167 } 0168 0169 template <class T> 0170 bool operator == (const T * t, SharedPtr <T> & s) { 0171 return (!t && !s.data) || (s.data && s.data->ptr == t); 0172 } 0173 0174 template <class T> 0175 inline SharedPtr<T> & SharedPtr<T>::operator = (const SharedPtr<T> & s) { 0176 if (data != s.data) { 0177 SharedData<T> * tmp = data; 0178 data = s.data; 0179 if (data) data->addRef (); 0180 if (tmp) tmp->release (); 0181 } 0182 return *this; 0183 } 0184 0185 template <class T> inline SharedPtr<T> & SharedPtr<T>::operator = (T * t) { 0186 if ((!data && t) || (data && data->ptr != t)) { 0187 if (data) data->release (); 0188 data = t ? new SharedData<T> (t, false) : 0L; 0189 } 0190 return *this; 0191 } 0192 0193 /** 0194 * Weak version of SharedPtr. This will also have access to the SharedData 0195 * pointer, only these object wont prevent destruction of the shared 0196 * pointer, hence weak references 0197 */ 0198 template <class T> 0199 struct WeakPtr { 0200 WeakPtr () : data (0L) {}; 0201 WeakPtr (T * t) : data (t ? new SharedData<T> (t, true) : 0) {} 0202 WeakPtr (T * t, bool /*b*/) : data (t ? new SharedData<T> (t, true) : 0) {} 0203 WeakPtr (const WeakPtr<T> & s) : data (s.data) { if (data) data->addWeakRef (); } 0204 WeakPtr (const SharedPtr<T> & s) : data (s.data) { if (data) data->addWeakRef (); } 0205 ~WeakPtr () { if (data) data->releaseWeak (); } 0206 WeakPtr<T> & operator = (const WeakPtr<T> &); 0207 WeakPtr<T> & operator = (const SharedPtr<T> &); 0208 WeakPtr<T> & operator = (T *); 0209 T * ptr () const { return data ? data->ptr : 0L; } 0210 T * operator -> () { return data ? data->ptr : 0L; } 0211 const T * operator -> () const { return data ? data->ptr : 0L; } 0212 T & operator * () { return *data->ptr; } 0213 const T & operator * () const { return *data->ptr; } 0214 // operator bool () const { return data && !!data->ptr; } 0215 bool operator == (const WeakPtr<T> & w) const { return data == w.data; } 0216 bool operator == (const SharedPtr<T> & s) const { return data == s.data; } 0217 bool operator == (const T * t) const { return (!t && !data) || (data && data->ptr == t); } 0218 bool operator == (T * t) const { return (!t && !data) || (data && data->ptr == t); } 0219 bool operator != (const WeakPtr<T> & w) const { return data != w.data; } 0220 bool operator != (const SharedPtr<T> & s) const { return data != s.data; } 0221 operator T * () { return data ? data->ptr : 0L; } 0222 operator const T * () const { return data ? data->ptr : 0L; } 0223 mutable SharedData<T> * data; 0224 }; 0225 0226 template <class T> 0227 bool operator == (T * t, WeakPtr <T> & s) { 0228 return (!t && !s.data) || (s.data && s.data->ptr == t); 0229 } 0230 0231 template <class T> 0232 bool operator == (const T * t, WeakPtr <T> & s) { 0233 return (!t && !s.data) || (s.data && s.data->ptr == t); 0234 } 0235 0236 template <class T> 0237 inline WeakPtr<T> & WeakPtr<T>::operator = (const WeakPtr<T> & w) { 0238 if (data != w.data) { 0239 SharedData<T> * tmp = data; 0240 data = w.data; 0241 if (data) data->addWeakRef (); 0242 if (tmp) tmp->releaseWeak (); 0243 } 0244 return *this; 0245 } 0246 0247 template <class T> 0248 inline WeakPtr<T> & WeakPtr<T>::operator = (const SharedPtr<T> & s) { 0249 if (data != s.data) { 0250 SharedData<T> * tmp = data; 0251 data = s.data; 0252 if (data) data->addWeakRef (); 0253 if (tmp) tmp->releaseWeak (); 0254 } 0255 return *this; 0256 } 0257 0258 template <class T> 0259 inline WeakPtr<T> & WeakPtr<T>::operator = (T * t) { 0260 if (data) data->releaseWeak (); 0261 data = t ? new SharedData<T> (t, true) : 0L; 0262 return *this; 0263 } 0264 0265 template <class T> inline SharedPtr<T>::SharedPtr (const WeakPtr <T> & w) : data (w.data) { 0266 if (data) data->addRef (); 0267 } 0268 0269 template <class T> 0270 inline SharedPtr<T> & SharedPtr<T>::operator = (const WeakPtr<T> & s) { 0271 if (data != s.data) { 0272 SharedData<T> * tmp = data; 0273 data = s.data; 0274 if (data) data->addRef (); 0275 if (tmp) tmp->release (); 0276 } 0277 return *this; 0278 } 0279 0280 template <class T> 0281 inline bool SharedPtr<T>::operator == (const WeakPtr<T> & w) const { 0282 return data == w.data; 0283 } 0284 0285 template <class T> 0286 inline bool SharedPtr<T>::operator != (const WeakPtr<T> & w) const { 0287 return data != w.data; 0288 } 0289 0290 } 0291 0292 #endif