00001
00002
00003 #ifndef SYNC_PTR_H_BY_DAVID_MAISONAVE_HEADER_GUARD_
00004 #define SYNC_PTR_H_BY_DAVID_MAISONAVE_HEADER_GUARD_
00005
00006 #include <memory>
00007 #include "sync_ctrl.h"
00008
00051 template<class T, class SYNC_T = sync_ctrl_default, class AX_TYPE = std::allocator<T>, class AX_SYNC_CTRL = std::allocator<SYNC_T> >
00052 class sync_ptr
00053 {
00054 protected:
00055 sync_ptr(T* type, SYNC_T *sync_ctrl_, int* RefCount_)
00056 :m_type(type), m_sync_ctrl(sync_ctrl_), m_RefCount(RefCount_)
00057 {
00058 m_sync_ctrl->lock();
00059 ++(*m_RefCount);
00060 m_sync_ctrl->unlock();
00061 }
00062 public:
00063 sync_ptr(T* type, SYNC_T *sync_ctrl_ = new SYNC_T)
00064 :m_type(type), m_sync_ctrl(sync_ctrl_), m_RefCount(new int(1)){}
00065 virtual ~sync_ptr()
00066 {
00067 m_sync_ctrl->lock();
00068 if (m_RefCount) --(*m_RefCount);
00069 if (!m_RefCount || !(*m_RefCount))
00070 {
00071 AX_TYPE alloc;
00072 alloc.destroy(m_type);
00073 alloc.deallocate(m_type, 1);
00074 m_type=NULL;
00075 if (m_RefCount) {delete m_RefCount;m_RefCount=NULL;}
00076 }
00077 m_sync_ctrl->unlock();
00078 if (!m_RefCount)
00079 {
00080 AX_SYNC_CTRL alloc;
00081 alloc.destroy(m_sync_ctrl);
00082 alloc.deallocate(m_sync_ctrl, 1);
00083 }
00084 }
00089 class RefLockPtr
00090 {
00091 struct RefData{
00092 int m_RefCount;
00093 T* m_type;
00094 SYNC_T *m_sync_ctrl;
00095 bool *m_trylock_stat;
00096 };
00097 public:
00098 friend class sync_ptr<T, SYNC_T, AX_TYPE, AX_SYNC_CTRL>;
00099 RefLockPtr(const RefLockPtr& Src):m_RefData(Src.m_RefData)
00100 {
00101 ++m_RefData->m_RefCount;
00102 }
00103 ~RefLockPtr()
00104 {
00105 --m_RefData->m_RefCount;
00106 if (!m_RefData->m_RefCount)
00107 {
00108 if (!m_RefData->m_trylock_stat || (*m_RefData->m_trylock_stat))
00109 {
00110 m_RefData->m_sync_ctrl->unlock();
00111 }
00112 delete m_RefData;
00113 m_RefData=NULL;
00114 }
00115 }
00116 T* operator->() const{return get_ptr();}
00117 T& operator*() const{return *get_ptr();}
00118 bool islocked()const{
00119 if (!m_RefData->m_trylock_stat || (*m_RefData->m_trylock_stat)) return true;
00120 return false;
00121 }
00122 protected:
00123 RefLockPtr(T* type, SYNC_T *sync_ctrl_, bool *trylock_stat = NULL)
00124 :m_RefData(new RefData)
00125 {
00126 m_RefData->m_RefCount = 1;
00127 m_RefData->m_type = type;
00128 m_RefData->m_sync_ctrl = sync_ctrl_;
00129 m_RefData->m_trylock_stat = trylock_stat;
00130 if(m_RefData->m_trylock_stat)
00131 {
00132 *m_RefData->m_trylock_stat = m_RefData->m_sync_ctrl->trylock();
00133 }
00134 else m_RefData->m_sync_ctrl->lock();
00135 }
00136 T* get_ptr()const
00137 {
00138 if (!m_RefData->m_trylock_stat || (*m_RefData->m_trylock_stat)) return m_RefData->m_type;
00139 return NULL;
00140 }
00141 RefLockPtr& operator=(const RefLockPtr&);
00142 RefData *m_RefData;
00143 };
00144 RefLockPtr operator->(){return RefLockPtr(m_type, m_sync_ctrl);}
00145 RefLockPtr operator*(){return RefLockPtr(m_type, m_sync_ctrl);}
00146
00147 RefLockPtr get_locked_obj(bool *trylock_stat = NULL){return RefLockPtr(m_type, m_sync_ctrl, trylock_stat);}
00148 protected:
00149 sync_ptr& operator=(const sync_ptr&);
00150 sync_ptr(const sync_ptr& Src);
00151 bool operator==(const sync_ptr&);
00152 bool operator!=(const sync_ptr&);
00153
00154 T* m_type;
00155 SYNC_T *m_sync_ctrl;
00156 int *m_RefCount;
00157 };
00158
00162 template<class T, class SYNC_T = sync_ctrl_default, class AX_TYPE = std::allocator<T>, class AX_SYNC_CTRL = std::allocator<SYNC_T> >
00163 class sync_ref_ptr : public sync_ptr<T, SYNC_T, AX_TYPE, AX_SYNC_CTRL>
00164 {
00165 public:
00166 sync_ref_ptr(const sync_ref_ptr& Src)
00167 :sync_ptr<T, SYNC_T, AX_TYPE, AX_SYNC_CTRL>(Src.m_type, Src.m_sync_ctrl, Src.m_RefCount){}
00168 sync_ref_ptr(T* type, SYNC_T *sync_ctrl_ = new SYNC_T)
00169 :sync_ptr<T, SYNC_T, AX_TYPE, AX_SYNC_CTRL>(type, sync_ctrl_){}
00170 private:
00171 sync_ref_ptr& operator=(const sync_ref_ptr&);
00172 bool operator==(const sync_ref_ptr&);
00173 bool operator!=(const sync_ref_ptr&);
00174 };
00175
00176 #endif
00177
00178