156 lines
3.6 KiB
C++
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_
|
|
|