// Copyright (C) 2003 Intel Corporation ////////////////////////////////////////////////////////////////////////// // SPtr.h // // This is a smart pointer class. It receives an initialized object in // the constructor, and maintains a reference count to this object. It // deletes the object only when the reference count reaches 0. // ////////////////////////////////////////////////////////////////////////// #ifndef _SPTR_H_ #define _SPTR_H_ #include #include "Semaphore.h" template class SPtr { public: // constructor explicit SPtr (T* ptr_p = 0) : _ptr(ptr_p), _pref_count (new int(1)), _psem(new Semaphore(1)) {} // copy constructor template SPtr (const SPtr& other_sptr_p) { other_sptr_p.getSem()->acquire(); _ptr = other_sptr_p.get(); _pref_count = other_sptr_p.getRefcnt(); _psem = other_sptr_p.getSem(); ++(*_pref_count); _psem->release(); } SPtr (const SPtr& other_sptr_p) { other_sptr_p.getSem()->acquire(); _ptr = other_sptr_p.get(); _pref_count = other_sptr_p.getRefcnt(); _psem = other_sptr_p.getSem(); ++(*_pref_count); _psem->release(); } // destructor ~SPtr () { _psem->acquire(); if (--(*_pref_count) == 0) { // delete pointer only on last destruction delete _pref_count; delete _psem; if (_ptr) { delete _ptr; } _ptr = 0; } else { _psem->release(); } } // operator= // if 'this' already points to an object, unreference it template SPtr & operator= (const SPtr& other_sptr_p) { if ((void*)&other_sptr_p == this) { return *this; } _psem->acquire(); if (--(*_pref_count) == 0) { delete _pref_count; delete _psem; if (_ptr) { delete _ptr; } } else { _psem->release(); } other_sptr_p.getSem()->acquire(); _ptr = (T *) other_sptr_p.get(); _pref_count = other_sptr_p.getRefcnt(); _psem = other_sptr_p.getSem(); ++(*_pref_count); _psem->release(); return *this; } SPtr & operator= (const SPtr& other_sptr_p) { if (&other_sptr_p == this) { return *this; } _psem->acquire(); if (--(*_pref_count) == 0) { delete _pref_count; delete _psem; if (_ptr) { delete _ptr; } } else { _psem->release(); } other_sptr_p.getSem()->acquire(); _ptr = other_sptr_p.get(); _pref_count = other_sptr_p.getRefcnt(); _psem = other_sptr_p.getSem(); ++(*_pref_count); _psem->release(); return *this; } // operator* T& operator*() const { return *_ptr; } // operator-> T* operator->() const { return _ptr; } // get - return inner pointer T* get() const { return _ptr; } int *getRefcnt() const { return _pref_count; } Semaphore *getSem() const { return _psem; } private: // the pointer itself T* _ptr; // a pointer to the reference count int *_pref_count; Semaphore *_psem; } ; template inline bool operator==(const SPtr& x, const SPtr& y) { return(x.get() == y.get()); } template inline bool operator!=(const SPtr& x, const SPtr& y) { return(x.get() != y.get()); } #endif // _SPTR_H_