156 lines
3.6 KiB
C++

// 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 <memory.h>
#include "Semaphore.h"
template
<class T>
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<class X>
SPtr (const SPtr<X>& 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<class X>
SPtr & operator= (const SPtr<X>& 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
<class T>
inline bool operator==(const SPtr<T>& x, const SPtr<T>& y) {
return(x.get() == y.get());
}
template
<class T>
inline bool operator!=(const SPtr<T>& x, const SPtr<T>& y) {
return(x.get() != y.get());
}
#endif // _SPTR_H_