RefCount.h
Go to the documentation of this file.
//----------------------------------------------------------------------------//
/*
* Copyright (c) 2009 Sony Pictures Imageworks Inc
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution. Neither the name of Sony Pictures Imageworks nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
#ifndef _INCLUDED_Field3D_REF_COUNT_H_
#define _INCLUDED_Field3D_REF_COUNT_H_
#define FIELD3D_USE_ATOMIC_COUNT
//----------------------------------------------------------------------------//
#include <boost/intrusive_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#ifdef FIELD3D_USE_ATOMIC_COUNT
#include <boost/detail/atomic_count.hpp>
#else
#include <boost/thread/mutex.hpp>
#endif
#include <string.h>
#include "Traits.h"
#include "ns.h"
FIELD3D_NAMESPACE_OPEN
//----------------------------------------------------------------------------//
// Field RTTI Replacement
//----------------------------------------------------------------------------//
#define DEFINE_CHECK_RTTI_CALL \
virtual bool checkRTTI(const char *typenameStr) \
{ return matchRTTI(typenameStr); } \
#define DEFINE_MATCH_RTTI_CALL \
bool matchRTTI(const char *typenameStr) \
{ \
if (strcmp(typenameStr,staticClassType()) == 0) { \
return true; \
} \
return base::matchRTTI(typenameStr); \
} \
#define DEFINE_FIELD_RTTI_CONCRETE_CLASS \
DEFINE_CHECK_RTTI_CALL \
DEFINE_MATCH_RTTI_CALL \
#define DEFINE_FIELD_RTTI_ABSTRACT_CLASS \
DEFINE_MATCH_RTTI_CALL \
//----------------------------------------------------------------------------//
// null_deleter (for shared_ptr)
//----------------------------------------------------------------------------//
struct null_deleter
{
void operator()(void const *) const
{ }
};
//----------------------------------------------------------------------------//
class FIELD3D_API RefBase
{
public:
// Typedefs ------------------------------------------------------------------
typedef boost::intrusive_ptr<RefBase> Ptr;
typedef boost::weak_ptr<RefBase> WeakPtr;
// Constructors --------------------------------------------------------------
RefBase()
: m_counter(0),
m_sharedPtr(this, null_deleter())
{ }
RefBase(const RefBase&)
: m_counter(0),
m_sharedPtr(this, null_deleter())
{ }
RefBase& operator= (const RefBase&)
{ return *this; }
virtual ~RefBase()
{}
// Reference counting --------------------------------------------------------
size_t refcnt()
{ return m_counter; }
void ref() const
{
#ifndef FIELD3D_USE_ATOMIC_COUNT
boost::mutex::scoped_lock lock(m_refMutex);
#endif
++m_counter;
}
void unref() const
{
#ifndef FIELD3D_USE_ATOMIC_COUNT
boost::mutex::scoped_lock lock(m_refMutex);
#endif
--m_counter;
// since we use intrusive_pointer no need
// to delete the object ourselves.
}
// Cache handling ------------------------------------------------------------
WeakPtr weakPtr() const
{ return m_sharedPtr; }
// RTTI replacement ----------------------------------------------------------
virtual bool checkRTTI(const char *typenameStr) = 0;
bool matchRTTI(const char *typenameStr)
{
if (strcmp(staticClassType(), typenameStr) == 0)
return true;
return false;
}
static const char *staticClassType()
{
return "RefBase";
}
private:
#ifdef FIELD3D_USE_ATOMIC_COUNT
mutable boost::detail::atomic_count m_counter;
#else
mutable long m_counter;
mutable boost::mutex m_refMutex;
#endif
boost::shared_ptr<RefBase> m_sharedPtr;
};
//----------------------------------------------------------------------------//
// Intrusive Pointer reference counting
//----------------------------------------------------------------------------//
inline void
intrusive_ptr_add_ref(RefBase* r)
{
r->ref();
}
//----------------------------------------------------------------------------//
inline void
intrusive_ptr_release(RefBase* r)
{
r->unref();
if (r->refcnt() == 0)
delete r;
}
//----------------------------------------------------------------------------//
// field_dynamic_cast
//----------------------------------------------------------------------------//
template <class Field_T>
typename Field_T::Ptr
field_dynamic_cast(RefBase::Ptr field)
{
if (!field)
return NULL;
const char *tgtTypeString = Field_T::staticClassType();
if (field->checkRTTI(tgtTypeString)) {
return static_cast<Field_T*>(field.get());
} else {
return NULL;
}
}
//#define FIELD_DYNAMIC_CAST boost::dynamic_pointer_cast
#define FIELD_DYNAMIC_CAST field_dynamic_cast
//----------------------------------------------------------------------------//
FIELD3D_NAMESPACE_HEADER_CLOSE
//----------------------------------------------------------------------------//
#endif // Include guard
intrusive_ptr_add_ref
void intrusive_ptr_add_ref(RefBase *r)
Definition RefCount.h:229
intrusive_ptr_release
void intrusive_ptr_release(RefBase *r)
Definition RefCount.h:239
Traits.h
RefBase
Definition RefCount.h:107
RefBase::matchRTTI
bool matchRTTI(const char *typenameStr)
Performs a check to see if the given typename string matches this class' This needs to be implemented...
Definition RefCount.h:193
RefBase::Ptr
boost::intrusive_ptr< RefBase > Ptr
Definition RefCount.h:112
RefBase::ref
void ref() const
Used by boost::intrusive_pointer.
Definition RefCount.h:150
RefBase::~RefBase
virtual ~RefBase()
Destructor.
Definition RefCount.h:138
RefBase::weakPtr
WeakPtr weakPtr() const
Definition RefCount.h:171
RefBase::checkRTTI
virtual bool checkRTTI(const char *typenameStr)=0
This function is only implemented by concrete classes and triggers the actual RTTI check through matc...
RefBase::m_sharedPtr
boost::shared_ptr< RefBase > m_sharedPtr
For use by the FieldCache only: The shared pointer lets us see if this object is still alive.
Definition RefCount.h:220
RefBase::WeakPtr
boost::weak_ptr< RefBase > WeakPtr
Definition RefCount.h:113
RefBase::refcnt
size_t refcnt()
Used by boost::intrusive_pointer.
Definition RefCount.h:146
RefBase::m_counter
boost::detail::atomic_count m_counter
For boost intrusive pointer.
Definition RefCount.h:211
RefBase::staticClassType
static const char * staticClassType()
Definition RefCount.h:200
RefBase::unref
void unref() const
Used by boost::intrusive_pointer.
Definition RefCount.h:159
RefBase::RefBase
RefBase(const RefBase &)
Copy constructor.
Definition RefCount.h:128
RefBase::RefBase
RefBase()
Definition RefCount.h:120
field_dynamic_cast
Field_T::Ptr field_dynamic_cast(RefBase::Ptr field)
Dynamic cast that uses string-comparison in order to be safe even after an object crosses a shared li...
Definition RefCount.h:256
FIELD3D_NAMESPACE_OPEN
Definition FieldMapping.cpp:74
ns.h
FIELD3D_API
#define FIELD3D_API
Definition ns.h:77
FIELD3D_NAMESPACE_HEADER_CLOSE
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Definition ns.h:58
null_deleter
Used to let a shared pointer exist that doesn't delete anything. This is used by RefBase to hold a sh...
Definition RefCount.h:99
null_deleter::operator()
void operator()(void const *) const
Definition RefCount.h:100