Use destroy() override instead of ContainerDeletePolicy for SharedObject

This commit is contained in:
Vinnie Falco
2013-09-06 09:55:58 -07:00
parent 718569d6a1
commit 85ced3dbf7
5 changed files with 26 additions and 40 deletions

View File

@@ -77,7 +77,6 @@ public:
virtual void* allocate (std::size_t size) = 0; virtual void* allocate (std::size_t size) = 0;
virtual void deallocate (void* p, std::size_t size) = 0; virtual void deallocate (void* p, std::size_t size) = 0;
virtual bool is_continuation () = 0; virtual bool is_continuation () = 0;
virtual void destroy () = 0;
static void pure_virtual_called (char const* fileName, int lineNumber); static void pure_virtual_called (char const* fileName, int lineNumber);
@@ -87,22 +86,6 @@ private:
friend void* asio_handler_allocate (std::size_t, SharedHandler*); friend void* asio_handler_allocate (std::size_t, SharedHandler*);
friend void asio_handler_deallocate (void*, std::size_t, SharedHandler*); friend void asio_handler_deallocate (void*, std::size_t, SharedHandler*);
friend bool asio_handler_is_continuation (SharedHandler*); friend bool asio_handler_is_continuation (SharedHandler*);
friend struct ContainerDeletePolicy <SharedHandler>;
};
//--------------------------------------------------------------------------
// For SharedPtr <SharedHandler>
template <>
struct ContainerDeletePolicy <SharedHandler>
{
// SharedPtr will use this when
// the reference count drops to zero.
//
inline static void destroy (SharedHandler* handler)
{
handler->destroy ();
}
}; };
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------

View File

@@ -69,9 +69,9 @@ protected:
#endif #endif
} }
// Called by our ContainerDeletePolicy hook to destroy the // Called by SharedObject hook to destroy the object. We need
// object. We need this because we allocated it using a custom // this because we allocated it using a custom allocator.
// allocator. Destruction is tricky, the algorithm is as follows: // Destruction is tricky, the algorithm is as follows:
// //
// First we move-assign the handler to our stack. If the build // First we move-assign the handler to our stack. If the build
// doesn't support move-assignment it will be a copy, still ok. // doesn't support move-assignment it will be a copy, still ok.

View File

@@ -79,20 +79,18 @@ public:
The return value indicates if the reference count dropped to zero, The return value indicates if the reference count dropped to zero,
so callers who know the derived type can use the ContainerDeletePolicy. so callers who know the derived type can use the ContainerDeletePolicy.
*/ */
inline bool decReferenceCount (bool doDelete = true) noexcept void decReferenceCount ()
{ {
bassert (getReferenceCount() > 0); bassert (getReferenceCount() > 0);
if (--refCount == 0) if (--refCount == 0)
{ destroy ();
if (doDelete)
delete this;
return true;
}
return false;
} }
/** Returns the object's current reference count. */ /** Returns the object's current reference count. */
inline int getReferenceCount() const noexcept { return refCount.get(); } inline int getReferenceCount() const noexcept
{
return refCount.get();
}
protected: protected:
//============================================================================== //==============================================================================
@@ -108,6 +106,14 @@ protected:
bassert (getReferenceCount() == 0); bassert (getReferenceCount() == 0);
} }
/** Destroy the object.
Derived classes can override this for different behaviors.
*/
virtual void destroy ()
{
delete this;
}
/** Resets the reference count to zero without deleting the object. /** Resets the reference count to zero without deleting the object.
You should probably never need to use this! You should probably never need to use this!
*/ */
@@ -155,17 +161,11 @@ public:
The return value indicates if the reference count dropped to zero, The return value indicates if the reference count dropped to zero,
so callers who know the derived type can use the ContainerDeletePolicy. so callers who know the derived type can use the ContainerDeletePolicy.
*/ */
inline bool decReferenceCount (bool doDelete = true) noexcept inline void decReferenceCount ()
{ {
bassert (getReferenceCount() > 0); bassert (getReferenceCount() > 0);
if (--refCount == 0) if (--refCount == 0)
{ destroy ();
if (doDelete)
delete this;
else
return true;
}
return false;
} }
/** Returns the object's current reference count. */ /** Returns the object's current reference count. */
@@ -184,6 +184,11 @@ protected:
bassert (getReferenceCount() == 0); bassert (getReferenceCount() == 0);
} }
virtual void destroy ()
{
delete this;
}
private: private:
//============================================================================== //==============================================================================
int refCount; int refCount;

View File

@@ -238,8 +238,7 @@ private:
static void release (T* t) static void release (T* t)
{ {
if (t != nullptr) if (t != nullptr)
if (t->decReferenceCount (false)) t->decReferenceCount ();
ContainerDeletePolicy <T>::destroy (t);
} }
// Swap ownership of the currently referenced object. // Swap ownership of the currently referenced object.

View File

@@ -139,11 +139,10 @@ public:
++m_refCount; ++m_refCount;
} }
inline bool decReferenceCount (bool = false) noexcept inline void decReferenceCount () noexcept
{ {
if (--m_refCount == 0) if (--m_refCount == 0)
destroySingleton (); destroySingleton ();
return false;
} }
// Caller must synchronize. // Caller must synchronize.