Fixed variation of bug 2022935 by changing when functions check if strong-count is zero.

git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@904 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
rich_sposato 2008-11-10 05:59:59 +00:00
parent 464f643e19
commit c983337def

View file

@ -3,12 +3,12 @@
// Copyright (c) 2006 Rich Sposato // Copyright (c) 2006 Rich Sposato
// The copyright on this file is protected under the terms of the MIT license. // The copyright on this file is protected under the terms of the MIT license.
// //
// Permission to use, copy, modify, distribute and sell this software for any // Permission to use, copy, modify, distribute and sell this software for any
// purpose is hereby granted without fee, provided that the above copyright // purpose is hereby granted without fee, provided that the above copyright
// notice appear in all copies and that both that copyright notice and this // notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation. // permission notice appear in supporting documentation.
// The author makes no representations about the // The author makes no representations about the
// suitability of this software for any purpose. It is provided "as is" // suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty. // without express or implied warranty.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_STRONG_PTR_INC_ #ifndef LOKI_STRONG_PTR_INC_
@ -117,7 +117,7 @@ namespace Loki
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// \class DeleteUsingFree /// \class DeleteUsingFree
/// ///
/// \ingroup StrongPointerDeleteGroup /// \ingroup StrongPointerDeleteGroup
/// Implementation of the DeletePolicy used by StrongPtr. Uses explicit call /// Implementation of the DeletePolicy used by StrongPtr. Uses explicit call
/// to T's destructor followed by call to free. This policy is useful for /// to T's destructor followed by call to free. This policy is useful for
/// managing the lifetime of pointers to structs returned by C functions. /// managing the lifetime of pointers to structs returned by C functions.
@ -148,7 +148,7 @@ public:
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// \class DeleteNothing /// \class DeleteNothing
/// ///
/// \ingroup StrongPointerDeleteGroup /// \ingroup StrongPointerDeleteGroup
/// Implementation of the DeletePolicy used by StrongPtr. This will never /// Implementation of the DeletePolicy used by StrongPtr. This will never
/// delete anything. You can use this policy with pointers to an undefined /// delete anything. You can use this policy with pointers to an undefined
/// type or a pure interface class with a protected destructor. /// type or a pure interface class with a protected destructor.
@ -174,7 +174,7 @@ public:
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// \class DeleteSingle /// \class DeleteSingle
/// ///
/// \ingroup StrongPointerDeleteGroup /// \ingroup StrongPointerDeleteGroup
/// Implementation of the DeletePolicy used by StrongPtr. This deletes just /// Implementation of the DeletePolicy used by StrongPtr. This deletes just
/// one shared object. This is the default class for the DeletePolicy. /// one shared object. This is the default class for the DeletePolicy.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -205,7 +205,7 @@ public:
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// \class DeleteArray /// \class DeleteArray
/// ///
/// \ingroup StrongPointerDeleteGroup /// \ingroup StrongPointerDeleteGroup
/// Implementation of the DeletePolicy used by StrongPtr. This deletes an /// Implementation of the DeletePolicy used by StrongPtr. This deletes an
/// array of shared objects. /// array of shared objects.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -236,7 +236,7 @@ public:
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// \class CantResetWithStrong /// \class CantResetWithStrong
/// ///
/// \ingroup StrongPointerResetGroup /// \ingroup StrongPointerResetGroup
/// Implementation of the ResetPolicy used by StrongPtr. This is the default /// Implementation of the ResetPolicy used by StrongPtr. This is the default
/// ResetPolicy for StrongPtr. It forbids reset and release only if a strong /// ResetPolicy for StrongPtr. It forbids reset and release only if a strong
/// copointer exists. /// copointer exists.
@ -259,7 +259,7 @@ struct CantResetWithStrong
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// \class AllowReset /// \class AllowReset
/// ///
/// \ingroup StrongPointerResetGroup /// \ingroup StrongPointerResetGroup
/// Implementation of the ResetPolicy used by StrongPtr. It allows reset and /// Implementation of the ResetPolicy used by StrongPtr. It allows reset and
/// release under any circumstance. /// release under any circumstance.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -280,7 +280,7 @@ struct AllowReset
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// \class NeverReset /// \class NeverReset
/// ///
/// \ingroup StrongPointerResetGroup /// \ingroup StrongPointerResetGroup
/// Implementation of the ResetPolicy used by StrongPtr. It forbids reset and /// Implementation of the ResetPolicy used by StrongPtr. It forbids reset and
/// release under any circumstance. /// release under any circumstance.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -359,10 +359,12 @@ public:
++m_weakCount; ++m_weakCount;
} }
inline void DecStrongCount( void ) inline bool DecStrongCount( void )
{ {
assert( 0 < m_strongCount ); assert( 0 < m_strongCount );
--m_strongCount; --m_strongCount;
const bool isZero = ( 0 == m_strongCount );
return isZero;
} }
inline void DecWeakCount( void ) inline void DecWeakCount( void )
@ -483,11 +485,12 @@ public:
m_Mutex.Unlock(); m_Mutex.Unlock();
} }
inline void DecStrongCount( void ) inline bool DecStrongCount( void )
{ {
m_Mutex.Lock(); m_Mutex.Lock();
TwoRefCountInfo::DecStrongCount(); const bool isZero = TwoRefCountInfo::DecStrongCount();
m_Mutex.Unlock(); m_Mutex.Unlock();
return isZero;
} }
inline void DecWeakCount( void ) inline void DecWeakCount( void )
@ -572,10 +575,6 @@ protected:
return Decrement( strong ); return Decrement( strong );
} }
void Increment( bool strong );
bool Decrement( bool strong );
bool HasStrongPointer( void ) const bool HasStrongPointer( void ) const
{ {
return m_counts->HasStrongPointer(); return m_counts->HasStrongPointer();
@ -604,6 +603,10 @@ private:
TwoRefCounts( void ); TwoRefCounts( void );
TwoRefCounts & operator = ( const TwoRefCounts & ); TwoRefCounts & operator = ( const TwoRefCounts & );
void Increment( bool strong );
bool Decrement( bool strong );
/// Pointer to all shared data. /// Pointer to all shared data.
Loki::Private::TwoRefCountInfo * m_counts; Loki::Private::TwoRefCountInfo * m_counts;
}; };
@ -696,15 +699,17 @@ protected:
bool Decrement( bool strong ) bool Decrement( bool strong )
{ {
bool noStrongPointers = false;
if ( strong ) if ( strong )
{ {
m_counts->DecStrongCount(); noStrongPointers = m_counts->DecStrongCount();
} }
else else
{ {
m_counts->DecWeakCount(); m_counts->DecWeakCount();
noStrongPointers = !m_counts->HasStrongPointer();
} }
return !m_counts->HasStrongPointer(); return noStrongPointers;
} }
bool HasStrongPointer( void ) const bool HasStrongPointer( void ) const
@ -832,7 +837,7 @@ private:
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// \class StrongPtr /// \class StrongPtr
/// ///
/// \ingroup SmartPointerGroup /// \ingroup SmartPointerGroup
/// ///
/// \param Strong default = true, /// \param Strong default = true,
/// \param OwnershipPolicy default = TwoRefCounts, /// \param OwnershipPolicy default = TwoRefCounts,
@ -855,7 +860,7 @@ template
template < class > class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS template < class > class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS
> >
class StrongPtr class StrongPtr
: public OwnershipPolicy : protected OwnershipPolicy
, public ConversionPolicy , public ConversionPolicy
, public CheckingPolicy< T * > , public CheckingPolicy< T * >
, public ResetPolicy< T > , public ResetPolicy< T >
@ -1059,7 +1064,7 @@ public:
} }
#else #else
template template
< <
typename T1, typename T1,
@ -1073,7 +1078,7 @@ public:
> >
friend bool ReleaseAll( StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & sp, friend bool ReleaseAll( StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & sp,
typename StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 >::StoredType & p ); typename StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 >::StoredType & p );
template template
< <
@ -1320,7 +1325,7 @@ private:
Tester(int) {} Tester(int) {}
void dummy() {} void dummy() {}
}; };
typedef void (Tester::*unspecified_boolean_type_)(); typedef void (Tester::*unspecified_boolean_type_)();
typedef typename Select< CP::allow, Tester, unspecified_boolean_type_ >::Result typedef typename Select< CP::allow, Tester, unspecified_boolean_type_ >::Result
@ -1339,11 +1344,11 @@ private:
{ {
Insipid(PointerType) {} Insipid(PointerType) {}
}; };
typedef typename Select< CP::allow, PointerType, Insipid >::Result typedef typename Select< CP::allow, PointerType, Insipid >::Result
AutomaticConversionResult; AutomaticConversionResult;
public: public:
operator AutomaticConversionResult() const operator AutomaticConversionResult() const
{ {
return GetPointer(); return GetPointer();