00001 #ifndef PHX_PTR_INTERFACE_H
00002 #define PHX_PTR_INTERFACE_H
00003
00004 #include <Phx/PhxConfig.h>
00005 #include <Phx/PhxTypes.h>
00006
00019 namespace Phx {
00020
00039 template <class T>
00040 class PtrInterface {
00041 public:
00042 typedef uint32_t ReferenceCount;
00043
00044 PtrInterface(void) : mReferenceCount(0) { }
00045
00051 void newReference(void) const {
00052 ++(const_cast<PtrInterface<T>*>(this))->mReferenceCount;
00053 }
00054
00060 void deleteReference(void) const {
00061 PtrInterface<T>* nonConst = const_cast<PtrInterface<T>*>(this);
00062 --nonConst->mReferenceCount;
00063 if (nonConst->mReferenceCount == 0) {
00064 nonConst->onZeroReferenceCount();
00065 }
00066 }
00067
00072 ReferenceCount referenceCount() const { return mReferenceCount; }
00073
00074 protected:
00075
00076 virtual ~PtrInterface() {}
00077
00078 private:
00087 virtual void onZeroReferenceCount(void) { delete this; }
00088
00089
00090 ReferenceCount mReferenceCount;
00091 };
00092
00093
00104 template <class T>
00105 class LockedPtrInterface {
00106 public:
00107 typedef uint32_t ReferenceCount;
00108
00109 LockedPtrInterface(void) : mReferenceCount(0) {
00110 if (pthread_mutex_init(&mLock, 0) != 0) {
00111 throw InternalException();
00112 }
00113 }
00114
00120 void newReference(void) const {
00121 LockedPtrInterface<T>* nonConst = const_cast<LockedPtrInterface<T>*>(this);
00122 pthread_mutex_lock(&nonConst->mLock);
00123 ++nonConst->mReferenceCount;
00124 pthread_mutex_unlock(&nonConst->mLock);
00125 }
00126
00132 void deleteReference(void) const {
00133 LockedPtrInterface<T>* nonConst = const_cast<LockedPtrInterface<T>*>(this);
00134 pthread_mutex_lock(&nonConst->mLock);
00135 --nonConst->mReferenceCount;
00136
00137 if (nonConst->mReferenceCount == 0) {
00138 pthread_mutex_unlock(&nonConst->mLock);
00139 nonConst->onZeroReferenceCount();
00140 } else {
00141 pthread_mutex_unlock(&nonConst->mLock);
00142 }
00143 }
00144
00149 ReferenceCount referenceCount() const {
00150 LockedPtrInterface<T>* nonConst = const_cast<LockedPtrInterface<T>*>(this);
00151 pthread_mutex_lock(&nonConst->mLock);
00152 ReferenceCount count = mReferenceCount;
00153 pthread_mutex_unlock(&nonConst->mLock);
00154 return count;
00155 }
00156
00157 protected:
00158
00159 virtual ~LockedPtrInterface() {
00160 pthread_mutex_destroy(&mLock);
00161 }
00162
00163 private:
00172 virtual void onZeroReferenceCount(void) { delete this; }
00173
00174
00175 ReferenceCount mReferenceCount;
00176 pthread_mutex_t mLock;
00177 };
00178
00179 };
00180
00181 #endif