00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef OPENALPP_REFERENCED
00015 #define OPENALPP_REFERENCED 1
00016
00017
00018 #include <openalpp/export.h>
00019
00020
00021
00022 #ifdef THREAD_SAFE_REF_UNREF
00023 #include <OpenThreads/ScopedLock>
00024 #include <OpenThreads/Mutex>
00025 #endif
00026
00027 namespace openalpp {
00028
00029
00030
00031 class DeleteHandler;
00032
00033
00035 class OPENALPP_API Referenced
00036 {
00037
00038 public:
00039 Referenced()
00040 {
00041
00042 _refCount=0;
00043 }
00044 Referenced(const Referenced&) {
00045 _refCount=0;
00046 }
00047
00048 inline Referenced& operator = (const Referenced&) { return *this; }
00049
00050 friend class DeleteHandler;
00051
00054 static void setDeleteHandler(DeleteHandler* handler);
00055
00057 static DeleteHandler* getDeleteHandler();
00058
00059
00062 inline void ref() const
00063 {
00064 #ifdef THREAD_SAFE_REF_UNREF
00065 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_refMutex);
00066 #endif
00067 ++_refCount;
00068 }
00069
00074 inline void unref() const;
00075
00082 inline void unref_nodelete() const { --_refCount; }
00083
00085 inline int referenceCount() const { return _refCount; }
00086
00087
00088 protected:
00089 virtual ~Referenced();
00090
00091 #ifdef THREAD_SAFE_REF_UNREF
00092 mutable OpenThreads::Mutex _refMutex;
00093 #endif
00094 mutable int _refCount;
00095
00096 };
00097
00098
00106 class DeleteHandler
00107 {
00108 public:
00109
00110 virtual ~DeleteHandler() {}
00111
00113 virtual void flush() {}
00114
00115 inline void doDelete(const Referenced* object) { delete object; }
00116
00121 virtual void requestDelete(const Referenced* object) { doDelete(object); }
00122 };
00123
00124 inline void Referenced::unref() const
00125 {
00126 bool needDelete = false;
00127 {
00128 #ifdef THREAD_SAFE_REF_UNREF
00129 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_refMutex);
00130 #endif
00131 --_refCount;
00132 needDelete = _refCount<=0;
00133 }
00134 if (needDelete)
00135 {
00136 if (getDeleteHandler()) getDeleteHandler()->requestDelete(this);
00137 else delete this;
00138 }
00139 }
00140
00141 }
00142
00143 #endif