402 lines
14 KiB
Plaintext
402 lines
14 KiB
Plaintext
// Filename: copyOnWritePointer.I
|
|
// Created by: drose (09Apr07)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PANDA 3D SOFTWARE
|
|
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
//
|
|
// All use of this software is subject to the terms of the revised BSD
|
|
// license. You should have received a copy of this license along
|
|
// with this source code in a file named "LICENSE."
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointer::Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE CopyOnWritePointer::
|
|
CopyOnWritePointer(CopyOnWriteObject *object) :
|
|
_cow_object(object)
|
|
{
|
|
if (_cow_object != (CopyOnWriteObject *)NULL) {
|
|
_cow_object->cache_ref();
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointer::Copy Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE CopyOnWritePointer::
|
|
CopyOnWritePointer(const CopyOnWritePointer ©) :
|
|
_cow_object(copy._cow_object)
|
|
{
|
|
if (_cow_object != (CopyOnWriteObject *)NULL) {
|
|
_cow_object->cache_ref();
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointer::Copy Assignment Operator
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void CopyOnWritePointer::
|
|
operator = (const CopyOnWritePointer ©) {
|
|
operator = (copy._cow_object);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointer::Assignment Operator
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void CopyOnWritePointer::
|
|
operator = (CopyOnWriteObject *object) {
|
|
if (_cow_object != object) {
|
|
if (_cow_object != (CopyOnWriteObject *)NULL) {
|
|
cache_unref_delete(_cow_object);
|
|
}
|
|
_cow_object = object;
|
|
if (_cow_object != (CopyOnWriteObject *)NULL) {
|
|
_cow_object->cache_ref();
|
|
}
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointer::Destructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE CopyOnWritePointer::
|
|
~CopyOnWritePointer() {
|
|
if (_cow_object != (CopyOnWriteObject *)NULL) {
|
|
cache_unref_delete(_cow_object);
|
|
}
|
|
}
|
|
|
|
#ifdef USE_MOVE_SEMANTICS
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointer::Move Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE CopyOnWritePointer::
|
|
CopyOnWritePointer(CopyOnWritePointer &&move) NOEXCEPT :
|
|
_cow_object(move._cow_object)
|
|
{
|
|
// Steal the other's reference count.
|
|
move._cow_object = (CopyOnWriteObject *)NULL;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointer::Move Assignment Operator
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void CopyOnWritePointer::
|
|
operator = (CopyOnWritePointer &&move) NOEXCEPT {
|
|
// Protect against self-move-assignment.
|
|
if (move._cow_object != _cow_object) {
|
|
CopyOnWriteObject *old_object = _cow_object;
|
|
_cow_object = move._cow_object;
|
|
move._cow_object = NULL;
|
|
|
|
if (old_object != (CopyOnWriteObject *)NULL) {
|
|
cache_unref_delete(old_object);
|
|
}
|
|
}
|
|
}
|
|
#endif // USE_MOVE_SEMANTICS
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointer::operator ==
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE bool CopyOnWritePointer::
|
|
operator == (const CopyOnWritePointer &other) const {
|
|
return _cow_object == other._cow_object;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointer::operator !=
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE bool CopyOnWritePointer::
|
|
operator != (const CopyOnWritePointer &other) const {
|
|
return _cow_object != other._cow_object;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointer::operator <
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE bool CopyOnWritePointer::
|
|
operator < (const CopyOnWritePointer &other) const {
|
|
return _cow_object < other._cow_object;
|
|
}
|
|
|
|
#ifndef COW_THREADED
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointer::get_read_pointer
|
|
// Access: Public
|
|
// Description: Returns a pointer locked for read. Until this
|
|
// pointer dereferences, calls to get_write_pointer()
|
|
// will force a copy.
|
|
//
|
|
// This flavor of the method is written for the
|
|
// non-threaded case.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE const CopyOnWriteObject *CopyOnWritePointer::
|
|
get_read_pointer() const {
|
|
return _cow_object;
|
|
}
|
|
#endif // COW_THREADED
|
|
|
|
#ifndef COW_THREADED
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointer::get_write_pointer
|
|
// Access: Public
|
|
// Description: Returns a pointer locked for write. If another
|
|
// thread or threads already hold the pointer locked for
|
|
// read, then this will force a copy.
|
|
//
|
|
// Until this pointer dereferences, calls to
|
|
// get_read_pointer() or get_write_pointer() will block.
|
|
//
|
|
// This flavor of the method is written for the
|
|
// non-threaded case.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE CopyOnWriteObject *CopyOnWritePointer::
|
|
get_write_pointer() {
|
|
if (_cow_object == (CopyOnWriteObject *)NULL) {
|
|
return NULL;
|
|
}
|
|
if (_cow_object->get_cache_ref_count() > 1) {
|
|
PT(CopyOnWriteObject) new_object = _cow_object->make_cow_copy();
|
|
cache_unref_delete(_cow_object);
|
|
_cow_object = new_object;
|
|
_cow_object->cache_ref();
|
|
}
|
|
return _cow_object;
|
|
}
|
|
#endif // COW_THREADED
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointer::get_unsafe_pointer
|
|
// Access: Public
|
|
// Description: Returns an unlocked pointer that you can write to.
|
|
// This should only be used in very narrow circumstances
|
|
// in which you know that no other thread may be
|
|
// accessing the pointer at the same time.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE CopyOnWriteObject *CopyOnWritePointer::
|
|
get_unsafe_pointer() {
|
|
return _cow_object;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointer::is_null
|
|
// Access: Public
|
|
// Description: Returns true if the CopyOnWritePointer contains a
|
|
// NULL pointer, false otherwise.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool CopyOnWritePointer::
|
|
is_null() const {
|
|
return (_cow_object == (CopyOnWriteObject *)NULL);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointer::clear
|
|
// Access: Public
|
|
// Description: Sets the pointer to NULL.
|
|
////////////////////////////////////////////////////////////////////
|
|
void CopyOnWritePointer::
|
|
clear() {
|
|
if (_cow_object != (CopyOnWriteObject *)NULL) {
|
|
cache_unref_delete(_cow_object);
|
|
}
|
|
_cow_object = NULL;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointer::test_ref_count_integrity
|
|
// Access: Published
|
|
// Description: Does some easy checks to make sure that the reference
|
|
// count isn't completely bogus. Returns true if ok,
|
|
// false otherwise.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE bool CopyOnWritePointer::
|
|
test_ref_count_integrity() const {
|
|
nassertr(_cow_object != (CopyOnWriteObject *)NULL, false);
|
|
return _cow_object->test_ref_count_integrity();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointer::test_ref_count_nonzero
|
|
// Access: Published
|
|
// Description: Does some easy checks to make sure that the reference
|
|
// count isn't zero, or completely bogus. Returns true
|
|
// if ok, false otherwise.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE bool CopyOnWritePointer::
|
|
test_ref_count_nonzero() const {
|
|
nassertr(_cow_object != (CopyOnWriteObject *)NULL, false);
|
|
return _cow_object->test_ref_count_nonzero();
|
|
}
|
|
|
|
#ifndef CPPPARSER
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointerTo::Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
template<class T>
|
|
INLINE CopyOnWritePointerTo<T>::
|
|
CopyOnWritePointerTo(To *object) : CopyOnWritePointer(object) {
|
|
}
|
|
#endif // CPPPARSER
|
|
|
|
#ifndef CPPPARSER
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointerTo::Copy Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
template<class T>
|
|
INLINE CopyOnWritePointerTo<T>::
|
|
CopyOnWritePointerTo(const CopyOnWritePointerTo<T> ©) :
|
|
CopyOnWritePointer(copy)
|
|
{
|
|
}
|
|
#endif // CPPPARSER
|
|
|
|
#ifndef CPPPARSER
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointerTo::Copy Assignment Operator
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
template<class T>
|
|
INLINE void CopyOnWritePointerTo<T>::
|
|
operator = (const CopyOnWritePointerTo<T> ©) {
|
|
CopyOnWritePointer::operator = (copy);
|
|
}
|
|
#endif // CPPPARSER
|
|
|
|
#ifndef CPPPARSER
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointer::Assignment Operator
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
template<class T>
|
|
INLINE void CopyOnWritePointerTo<T>::
|
|
operator = (To *object) {
|
|
CopyOnWritePointer::operator = (object);
|
|
}
|
|
#endif // CPPPARSER
|
|
|
|
#ifdef USE_MOVE_SEMANTICS
|
|
#ifndef CPPPARSER
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointerTo::Move Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
template<class T>
|
|
INLINE CopyOnWritePointerTo<T>::
|
|
CopyOnWritePointerTo(CopyOnWritePointerTo<T> &&move) NOEXCEPT :
|
|
CopyOnWritePointer((CopyOnWritePointer &&)move)
|
|
{
|
|
}
|
|
#endif // CPPPARSER
|
|
|
|
#ifndef CPPPARSER
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointerTo::Move Assignment Operator
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
template<class T>
|
|
INLINE void CopyOnWritePointerTo<T>::
|
|
operator = (CopyOnWritePointerTo<T> &&move) NOEXCEPT {
|
|
CopyOnWritePointer::operator = ((CopyOnWritePointer &&)move);
|
|
}
|
|
#endif // CPPPARSER
|
|
#endif // USE_MOVE_SEMANTICS
|
|
|
|
#ifndef CPPPARSER
|
|
#ifdef COW_THREADED
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointerTo::get_read_pointer
|
|
// Access: Public
|
|
// Description: See CopyOnWritePointer::get_read_pointer().
|
|
////////////////////////////////////////////////////////////////////
|
|
template<class T>
|
|
INLINE CPT(TYPENAME CopyOnWritePointerTo<T>::To) CopyOnWritePointerTo<T>::
|
|
get_read_pointer() const {
|
|
return (const To *)(CopyOnWritePointer::get_read_pointer().p());
|
|
}
|
|
#else // COW_THREADED
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointerTo::get_read_pointer
|
|
// Access: Public
|
|
// Description: See CopyOnWritePointer::get_read_pointer().
|
|
////////////////////////////////////////////////////////////////////
|
|
template<class T>
|
|
INLINE const TYPENAME CopyOnWritePointerTo<T>::To *CopyOnWritePointerTo<T>::
|
|
get_read_pointer() const {
|
|
return (const To *)CopyOnWritePointer::get_read_pointer();
|
|
}
|
|
#endif // COW_THREADED
|
|
#endif // CPPPARSER
|
|
|
|
#ifndef CPPPARSER
|
|
#ifdef COW_THREADED
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointerTo::get_write_pointer
|
|
// Access: Public
|
|
// Description: See CopyOnWritePointer::get_write_pointer().
|
|
////////////////////////////////////////////////////////////////////
|
|
template<class T>
|
|
INLINE PT(TYPENAME CopyOnWritePointerTo<T>::To) CopyOnWritePointerTo<T>::
|
|
get_write_pointer() {
|
|
return (To *)(CopyOnWritePointer::get_write_pointer().p());
|
|
}
|
|
#else // COW_THREADED
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointerTo::get_write_pointer
|
|
// Access: Public
|
|
// Description: See CopyOnWritePointer::get_write_pointer().
|
|
////////////////////////////////////////////////////////////////////
|
|
template<class T>
|
|
INLINE TYPENAME CopyOnWritePointerTo<T>::To *CopyOnWritePointerTo<T>::
|
|
get_write_pointer() {
|
|
return (To *)CopyOnWritePointer::get_write_pointer();
|
|
}
|
|
#endif // COW_THREADED
|
|
#endif // CPPPARSER
|
|
|
|
#ifndef CPPPARSER
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: CopyOnWritePointerTo::get_unsafe_pointer
|
|
// Access: Public
|
|
// Description: See CopyOnWritePointer::get_unsafe_pointer().
|
|
////////////////////////////////////////////////////////////////////
|
|
template<class T>
|
|
INLINE TYPENAME CopyOnWritePointerTo<T>::To *CopyOnWritePointerTo<T>::
|
|
get_unsafe_pointer() {
|
|
return (To *)(CopyOnWritePointer::get_unsafe_pointer());
|
|
}
|
|
#endif // CPPPARSER
|