shared_ptr memory leak testing. Make increment and decrement counts thread safe. Fix template test.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@9977 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
035cdf6f1a
commit
54200cc7e8
5 changed files with 322 additions and 55 deletions
100
Examples/test-suite/shared_ptr_wrapper.h
Normal file
100
Examples/test-suite/shared_ptr_wrapper.h
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
// defines SwigBoost::shared_ptr, a wrapper around boost::shared_ptr
|
||||
// Use this shared_ptr wrapper for testing memory leaks of shared_ptr.
|
||||
// getTotalCount() should return zero at end of test
|
||||
|
||||
#include <iostream>
|
||||
|
||||
struct SWIG_null_deleter; // forward reference, definition is in shared_ptr.i
|
||||
namespace SwigBoost {
|
||||
// This template can be specialized for better debugging information
|
||||
template <typename T> std::string show_message(boost::shared_ptr<T>*t) {
|
||||
if (!t)
|
||||
return "null shared_ptr!!!";
|
||||
if (boost::get_deleter<SWIG_null_deleter>(*t))
|
||||
return std::string(typeid(t).name()) + " NULL DELETER";
|
||||
if (*t)
|
||||
return std::string(typeid(t).name()) + " object";
|
||||
else
|
||||
return std::string(typeid(t).name()) + " NULL";
|
||||
}
|
||||
|
||||
namespace SharedPtrWrapper {
|
||||
static SwigExamples::CriticalSection critical_section;
|
||||
static int total_count = 0;
|
||||
|
||||
template<typename T> void increment(boost::shared_ptr<T>* ptr) {
|
||||
SwigExamples::Lock lock(critical_section);
|
||||
std::cout << ptr << " " << show_message(ptr) << " " << " +" << std::endl << std::flush;
|
||||
total_count++;
|
||||
}
|
||||
template<typename T> void decrement(boost::shared_ptr<T>* ptr) {
|
||||
SwigExamples::Lock lock(critical_section);
|
||||
std::cout << ptr << " " << show_message(ptr) << " " << " -" << std::endl << std::flush;
|
||||
total_count--;
|
||||
}
|
||||
static int getTotalCount() { return total_count; }
|
||||
}
|
||||
|
||||
template<typename T> class shared_ptr {
|
||||
private:
|
||||
typedef shared_ptr<T> this_type;
|
||||
public:
|
||||
typedef typename boost::detail::shared_ptr_traits<T>::reference reference;
|
||||
|
||||
shared_ptr() : m_shared_ptr() {
|
||||
SharedPtrWrapper::increment(&m_shared_ptr);
|
||||
}
|
||||
template<typename Y> explicit shared_ptr(Y* p) : m_shared_ptr(p) {
|
||||
SharedPtrWrapper::increment(&m_shared_ptr);
|
||||
}
|
||||
template<typename Y, typename D> explicit shared_ptr(Y* p, D d) : m_shared_ptr(p, d) {
|
||||
SharedPtrWrapper::increment(&m_shared_ptr);
|
||||
}
|
||||
|
||||
shared_ptr(shared_ptr const & other)
|
||||
: m_shared_ptr(other.m_shared_ptr)
|
||||
{
|
||||
SharedPtrWrapper::increment(&m_shared_ptr);
|
||||
}
|
||||
|
||||
template<typename Y> shared_ptr(shared_ptr<Y> const & other)
|
||||
: m_shared_ptr(other.m_shared_ptr)
|
||||
{
|
||||
SharedPtrWrapper::increment(&m_shared_ptr);
|
||||
}
|
||||
|
||||
reference operator*() const {
|
||||
return m_shared_ptr.operator*();
|
||||
}
|
||||
T* operator->() const {
|
||||
return m_shared_ptr.operator->();
|
||||
}
|
||||
T* get() const {
|
||||
return m_shared_ptr.get();
|
||||
}
|
||||
operator bool() const {
|
||||
return m_shared_ptr.get() == 0 ? false : true;
|
||||
}
|
||||
bool unique() const {
|
||||
return m_shared_ptr.unique();
|
||||
}
|
||||
long use_count() const {
|
||||
return m_shared_ptr.use_count();
|
||||
}
|
||||
void swap(shared_ptr<T>& other) {
|
||||
std::swap(m_shared_ptr, other.m_shared_ptr);
|
||||
}
|
||||
template<class Y> bool _internal_less(shared_ptr<Y> const & rhs) const {
|
||||
return m_shared_ptr < rhs.m_shared_ptr;
|
||||
}
|
||||
~shared_ptr() {
|
||||
SharedPtrWrapper::decrement(&m_shared_ptr);
|
||||
}
|
||||
|
||||
private:
|
||||
template<class Y> friend class shared_ptr;
|
||||
|
||||
boost::shared_ptr<T> m_shared_ptr;
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue