/* PCSX2 - PS2 Emulator for PCs * Copyright (C) 2002-2010 PCSX2 Dev Team * * PCSX2 is free software: you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with PCSX2. * If not, see . */ #pragma once #include "Threading.h" using Threading::ScopedLock; // -------------------------------------------------------------------------------------- // ScopedPtrMT // -------------------------------------------------------------------------------------- template< typename T > class ScopedPtrMT { DeclareNoncopyableObject(ScopedPtrMT); typedef T* TPtr; protected: volatile TPtr m_ptr; Threading::Mutex m_mtx; public: typedef T element_type; wxEXPLICIT ScopedPtrMT(T * ptr = NULL) { m_ptr = ptr; } ~ScopedPtrMT() throw() { _Delete_unlocked(); } ScopedPtrMT& Reassign(T * ptr = NULL) { TPtr doh = (TPtr)Threading::AtomicExchangePointer( m_ptr, ptr ); if ( ptr != doh ) delete doh; return *this; } ScopedPtrMT& Delete() throw() { ScopedLock lock( m_mtx ); _Delete_unlocked(); } // Removes the pointer from scoped management, but does not delete! // (ScopedPtr will be NULL after this method) T *DetachPtr() { ScopedLock lock( m_mtx ); T *ptr = m_ptr; m_ptr = NULL; return ptr; } // Returns the managed pointer. Can return NULL as a valid result if the ScopedPtrMT // has no object in management. T* GetPtr() const { return m_ptr; } void SwapPtr(ScopedPtrMT& other) { ScopedLock lock( m_mtx ); T * const tmp = other.m_ptr; other.m_ptr = m_ptr; m_ptr = tmp; } // ---------------------------------------------------------------------------- // ScopedPtrMT Operators // ---------------------------------------------------------------------------- // I've decided to use the ATL's approach to pointer validity tests, opposed to // the wx/boost approach (which uses some bizarre member method pointer crap, and can't // allow the T* implicit casting. bool operator!() const throw() { return m_ptr == NULL; } // Equality bool operator==(T* pT) const throw() { return m_ptr == pT; } // Inequality bool operator!=(T* pT) const throw() { return !operator==(pT); } // Convenient assignment operator. ScopedPtrMT = NULL will issue an automatic deletion // of the managed pointer. ScopedPtrMT& operator=( T* src ) { return Reassign( src ); } #if 0 operator T*() const { return m_ptr; } // Dereference operator, returns a handle to the managed pointer. // Generates a debug assertion if the object is NULL! T& operator*() const { pxAssert(m_ptr != NULL); return *m_ptr; } T* operator->() const { pxAssert(m_ptr != NULL); return m_ptr; } #endif protected: void _Delete_unlocked() throw() { delete m_ptr; m_ptr = NULL; } };