From a7b2855412cd8d20f426d8061098a79d43788706 Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Sat, 19 Jun 2010 13:42:32 +0000 Subject: [PATCH] Refactoring: (boring) * renamed PersistentThread to pxThread (shorter, sweeter, and the 'persistent' part is obsolete since its now a full blown thread manager since some while ago). * Renamed a bunch of the PostMethodToMain stuff to Rpc_TryInvoke* (for remote procedure call). It's probably not a good use of the term, but I'm bummed I can't think of anything better/shorter. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3238 96395faa-99c1-11dd-bbfe-3dabce05a288 --- common/include/Utilities/PersistentThread.h | 28 ++--- common/include/Utilities/Threading.h | 22 ++-- common/include/Utilities/pxEvents.h | 33 +++--- common/include/Utilities/wxAppWithHelpers.h | 21 ++-- common/src/Utilities/ThreadTools.cpp | 108 +++++++++---------- common/src/Utilities/Windows/WinThreads.cpp | 8 +- common/src/Utilities/wxAppWithHelpers.cpp | 110 +++++++++++++------- pcsx2/System/SysThreads.h | 4 +- pcsx2/ZipTools/ThreadedZipTools.h | 4 +- pcsx2/gui/App.h | 4 +- pcsx2/gui/AppCorePlugins.cpp | 22 ++-- pcsx2/gui/AppCoreThread.cpp | 2 +- pcsx2/gui/AppEventListeners.h | 4 +- pcsx2/gui/AppEventSources.cpp | 4 +- pcsx2/gui/AppInit.cpp | 18 +++- pcsx2/gui/AppMain.cpp | 37 ++++--- pcsx2/gui/ConsoleLogger.h | 4 +- pcsx2/gui/Dialogs/ModalPopups.h | 2 +- pcsx2/gui/Dialogs/StuckThreadDialog.cpp | 2 +- pcsx2/gui/ExecutorThread.cpp | 6 +- pcsx2/gui/MessageBoxes.cpp | 2 +- pcsx2/gui/Panels/ConfigurationPanels.h | 4 +- pcsx2/gui/Panels/PluginSelectorPanel.cpp | 6 +- pcsx2/gui/UpdateUI.cpp | 16 +-- pcsx2/gui/pxEventThread.h | 4 +- pcsx2/windows/WinConsolePipe.cpp | 4 +- 26 files changed, 269 insertions(+), 210 deletions(-) diff --git a/common/include/Utilities/PersistentThread.h b/common/include/Utilities/PersistentThread.h index 89ec379416..3016eea217 100644 --- a/common/include/Utilities/PersistentThread.h +++ b/common/include/Utilities/PersistentThread.h @@ -23,7 +23,7 @@ namespace Threading { // -------------------------------------------------------------------------------------- -// IThread - Interface for the public access to PersistentThread. +// IThread - Interface for the public access to pxThread. // -------------------------------------------------------------------------------------- // Class usage: Can be used for allowing safe nullification of a thread handle. Rather // than being NULL'd, the handle can be mapped to an IThread implementation which acts @@ -55,7 +55,7 @@ namespace Threading typedef int EvtParams; protected: - PersistentThread* m_thread; + pxThread* m_thread; public: EventListener_Thread() @@ -65,8 +65,8 @@ namespace Threading virtual ~EventListener_Thread() throw() {} - void SetThread( PersistentThread& thr ) { m_thread = &thr; } - void SetThread( PersistentThread* thr ) { m_thread = thr; } + void SetThread( pxThread& thr ) { m_thread = &thr; } + void SetThread( pxThread* thr ) { m_thread = thr; } void DispatchEvent( const int& params ) { @@ -74,7 +74,7 @@ namespace Threading } protected: - // Invoked by the PersistentThread when the thread execution is ending. This is + // Invoked by the pxThread when the thread execution is ending. This is // typically more useful than a delete listener since the extended thread information // provided by virtualized functions/methods will be available. // Important! This event is executed *by the thread*, so care must be taken to ensure @@ -83,7 +83,7 @@ namespace Threading }; // -------------------------------------------------------------------------------------- -// PersistentThread - Helper class for the basics of starting/managing persistent threads. +// pxThread - Helper class for the basics of starting/managing persistent threads. // -------------------------------------------------------------------------------------- // This class is meant to be a helper for the typical threading model of "start once and // reuse many times." This class incorporates a lot of extra overhead in stopping and @@ -109,9 +109,9 @@ namespace Threading // no dependency options for ensuring correct static var initializations). Use heap // allocation to create thread objects instead. // - class PersistentThread : public virtual IThread + class pxThread : public virtual IThread { - DeclareNoncopyableObject(PersistentThread); + DeclareNoncopyableObject(pxThread); friend void pxYield( int ms ); @@ -137,9 +137,9 @@ namespace Threading public: - virtual ~PersistentThread() throw(); - PersistentThread(); - PersistentThread( const char* name ); + virtual ~pxThread() throw(); + pxThread(); + pxThread( const char* name ); pthread_t GetId() const { return m_thread; } u64 GetCpuTime() const; @@ -177,7 +177,7 @@ namespace Threading virtual void OnStartInThread(); - // This is called when the thread has been canceled or exits normally. The PersistentThread + // This is called when the thread has been canceled or exits normally. The pxThread // automatically binds it to the pthread cleanup routines as soon as the thread starts. virtual void OnCleanupInThread(); @@ -217,7 +217,7 @@ namespace Threading void _DoSetThreadName( const wxString& name ); void _DoSetThreadName( const char* name ); void _internal_execute(); - void _try_virtual_invoke( void (PersistentThread::*method)() ); + void _try_virtual_invoke( void (pxThread::*method)() ); void _ThreadCleanup(); static void* _internal_callback( void* func ); @@ -262,7 +262,7 @@ namespace Threading // into smaller sections. For example, if you have 20,000 items to process, the task // can be divided into two threads of 10,000 items each. // - class BaseTaskThread : public PersistentThread + class BaseTaskThread : public pxThread { protected: volatile bool m_Done; diff --git a/common/include/Utilities/Threading.h b/common/include/Utilities/Threading.h index 4436a89e18..61a4ddcefe 100644 --- a/common/include/Utilities/Threading.h +++ b/common/include/Utilities/Threading.h @@ -47,17 +47,17 @@ class wxTimeSpan; namespace Threading { - class PersistentThread; + class pxThread; class RwMutex; extern void pxTestCancel(); - extern PersistentThread* pxGetCurrentThread(); + extern pxThread* pxGetCurrentThread(); extern wxString pxGetCurrentThreadName(); extern u64 GetThreadCpuTime(); extern u64 GetThreadTicksPerSecond(); // Yields the current thread and provides cancellation points if the thread is managed by - // PersistentThread. Unmanaged threads use standard Sleep. + // pxThread. Unmanaged threads use standard Sleep. extern void pxYield( int ms ); } @@ -66,17 +66,17 @@ namespace Exception class BaseThreadError : public virtual RuntimeError { public: - Threading::PersistentThread* m_thread; + Threading::pxThread* m_thread; DEFINE_EXCEPTION_COPYTORS( BaseThreadError ) - explicit BaseThreadError( Threading::PersistentThread* _thread=NULL ) + explicit BaseThreadError( Threading::pxThread* _thread=NULL ) { m_thread = _thread; BaseException::InitBaseEx( "Unspecified thread error" ); } - BaseThreadError( Threading::PersistentThread& _thread ) + BaseThreadError( Threading::pxThread& _thread ) { m_thread = &_thread; BaseException::InitBaseEx( "Unspecified thread error" ); @@ -85,8 +85,8 @@ namespace Exception virtual wxString FormatDiagnosticMessage() const; virtual wxString FormatDisplayMessage() const; - Threading::PersistentThread& Thread(); - const Threading::PersistentThread& Thread() const; + Threading::pxThread& Thread(); + const Threading::pxThread& Thread() const; }; class ThreadCreationError : public virtual BaseThreadError @@ -94,19 +94,19 @@ namespace Exception public: DEFINE_EXCEPTION_COPYTORS( ThreadCreationError ) - explicit ThreadCreationError( Threading::PersistentThread* _thread=NULL, const char* msg="Creation of thread '%s' failed." ) + explicit ThreadCreationError( Threading::pxThread* _thread=NULL, const char* msg="Creation of thread '%s' failed." ) { m_thread = _thread; BaseException::InitBaseEx( msg ); } - ThreadCreationError( Threading::PersistentThread& _thread, const char* msg="Creation of thread '%s' failed." ) + ThreadCreationError( Threading::pxThread& _thread, const char* msg="Creation of thread '%s' failed." ) { m_thread = &_thread; BaseException::InitBaseEx( msg ); } - ThreadCreationError( Threading::PersistentThread& _thread, const wxString& msg_diag, const wxString& msg_user ) + ThreadCreationError( Threading::pxThread& _thread, const wxString& msg_diag, const wxString& msg_user ) { m_thread = &_thread; BaseException::InitBaseEx( msg_diag, msg_user ); diff --git a/common/include/Utilities/pxEvents.h b/common/include/Utilities/pxEvents.h index b3a2e01a80..04dc516564 100644 --- a/common/include/Utilities/pxEvents.h +++ b/common/include/Utilities/pxEvents.h @@ -75,7 +75,7 @@ class pxSimpleEvent : public wxEvent DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxSimpleEvent) public: - pxSimpleEvent( int evtid=0 ) + explicit pxSimpleEvent( int evtid=0 ) : wxEvent(0, evtid) { } @@ -87,22 +87,22 @@ public: }; // -------------------------------------------------------------------------------------- -// pxInvokeActionEvent +// pxActionEvent // -------------------------------------------------------------------------------------- -class pxInvokeActionEvent : public wxEvent +class pxActionEvent : public wxEvent { - DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxInvokeActionEvent) + DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxActionEvent) protected: SynchronousActionState* m_state; public: - virtual ~pxInvokeActionEvent() throw() { } - virtual pxInvokeActionEvent *Clone() const { return new pxInvokeActionEvent(*this); } + virtual ~pxActionEvent() throw() { } + virtual pxActionEvent *Clone() const { return new pxActionEvent(*this); } - explicit pxInvokeActionEvent( SynchronousActionState* sema=NULL, int msgtype=pxEvt_InvokeAction ); - explicit pxInvokeActionEvent( SynchronousActionState& sema, int msgtype=pxEvt_InvokeAction ); - pxInvokeActionEvent( const pxInvokeActionEvent& src ); + explicit pxActionEvent( SynchronousActionState* sema=NULL, int msgtype=pxEvt_InvokeAction ); + explicit pxActionEvent( SynchronousActionState& sema, int msgtype=pxEvt_InvokeAction ); + pxActionEvent( const pxActionEvent& src ); Threading::Semaphore* GetSemaphore() const { return m_state ? &m_state->GetSemaphore() : NULL; } @@ -118,6 +118,13 @@ public: virtual void _DoInvokeEvent(); protected: + // Extending classes should implement this method to perfoem whatever action it is + // the event is supposed to do. :) Thread affinity is garaunteed to be the Main/UI + // thread, and exceptions will be handled automatically. + // + // Exception note: exceptions are passed back to the thread that posted the event + // to the queue, when possible. If the calling thread is not blocking for a result + // from this event, then the exception will be posted to the Main/UI thread instead. virtual void InvokeEvent() {} }; @@ -125,9 +132,9 @@ protected: // -------------------------------------------------------------------------------------- // pxExceptionEvent // -------------------------------------------------------------------------------------- -class pxExceptionEvent : public pxInvokeActionEvent +class pxExceptionEvent : public pxActionEvent { - typedef pxInvokeActionEvent _parent; + typedef pxActionEvent _parent; protected: BaseException* m_except; @@ -184,9 +191,9 @@ public: // -------------------------------------------------------------------------------------- // BaseMessageBoxEvent // -------------------------------------------------------------------------------------- -class BaseMessageBoxEvent : public pxInvokeActionEvent +class BaseMessageBoxEvent : public pxActionEvent { - typedef pxInvokeActionEvent _parent; + typedef pxActionEvent _parent; DECLARE_DYNAMIC_CLASS_NO_ASSIGN(BaseMessageBoxEvent) protected: diff --git a/common/include/Utilities/wxAppWithHelpers.h b/common/include/Utilities/wxAppWithHelpers.h index 045ca8735d..6a4492aeeb 100644 --- a/common/include/Utilities/wxAppWithHelpers.h +++ b/common/include/Utilities/wxAppWithHelpers.h @@ -74,8 +74,8 @@ public: DeleteObject( *obj ); } - void DeleteThread( Threading::PersistentThread& obj ); - void DeleteThread( Threading::PersistentThread* obj ) + void DeleteThread( Threading::pxThread& obj ); + void DeleteThread( Threading::pxThread* obj ) { if( obj == NULL ) return; DeleteThread( *obj ); @@ -85,15 +85,16 @@ public: void PostCommand( int evtType, int intParam=0, long longParam=0, const wxString& stringParam=wxEmptyString ); void PostMethod( FnType_Void* method ); void PostIdleMethod( FnType_Void* method ); - void ProcessMethod( void (*method)() ); + void ProcessMethod( FnType_Void* method ); + + bool Rpc_TryInvoke( FnType_Void* method ); + bool Rpc_TryInvokeAsync( FnType_Void* method ); sptr ProcessCommand( void* clientData, int evtType, int intParam=0, long longParam=0, const wxString& stringParam=wxEmptyString ); sptr ProcessCommand( int evtType, int intParam=0, long longParam=0, const wxString& stringParam=wxEmptyString ); - void ProcessAction( pxInvokeActionEvent& evt ); - void PostAction( const pxInvokeActionEvent& evt ); - - bool PostMethodMyself( void (*method)() ); + void ProcessAction( pxActionEvent& evt ); + void PostAction( const pxActionEvent& evt ); void Ping(); bool OnInit(); @@ -105,8 +106,8 @@ public: bool ProcessEvent( wxEvent& evt ); bool ProcessEvent( wxEvent* evt ); - bool ProcessEvent( pxInvokeActionEvent& evt ); - bool ProcessEvent( pxInvokeActionEvent* evt ); + bool ProcessEvent( pxActionEvent& evt ); + bool ProcessEvent( pxActionEvent* evt ); protected: void IdleEventDispatcher( const wxChar* action ); @@ -117,7 +118,7 @@ protected: void OnDeleteObject( wxCommandEvent& evt ); void OnDeleteThread( wxCommandEvent& evt ); void OnSynchronousCommand( pxSynchronousCommandEvent& evt ); - void OnInvokeAction( pxInvokeActionEvent& evt ); + void OnInvokeAction( pxActionEvent& evt ); }; diff --git a/common/src/Utilities/ThreadTools.cpp b/common/src/Utilities/ThreadTools.cpp index 9fb9b611fd..d03a0c334c 100644 --- a/common/src/Utilities/ThreadTools.cpp +++ b/common/src/Utilities/ThreadTools.cpp @@ -90,19 +90,19 @@ void Threading::pxTestCancel() } // Returns a handle to the current persistent thread. If the current thread does not belong -// to the PersistentThread table, NULL is returned. Since the main/ui thread is not created -// through PersistentThread it will also return NULL. Callers can use wxThread::IsMain() to +// to the pxThread table, NULL is returned. Since the main/ui thread is not created +// through pxThread it will also return NULL. Callers can use wxThread::IsMain() to // test if the NULL thread is the main thread. -PersistentThread* Threading::pxGetCurrentThread() +pxThread* Threading::pxGetCurrentThread() { - return (curthread_key==NULL) ? NULL : (PersistentThread*)pthread_getspecific( curthread_key ); + return (curthread_key==NULL) ? NULL : (pxThread*)pthread_getspecific( curthread_key ); } -// returns the name of the current thread, or "Unknown" if the thread is neither a PersistentThread +// returns the name of the current thread, or "Unknown" if the thread is neither a pxThread // nor the Main/UI thread. wxString Threading::pxGetCurrentThreadName() { - if( PersistentThread* thr = pxGetCurrentThread() ) + if( pxThread* thr = pxGetCurrentThread() ) { return thr->GetName(); } @@ -116,7 +116,7 @@ wxString Threading::pxGetCurrentThreadName() void Threading::pxYield( int ms ) { - if( PersistentThread* thr = pxGetCurrentThread() ) + if( pxThread* thr = pxGetCurrentThread() ) thr->Yield( ms ); else Sleep( ms ); @@ -148,14 +148,14 @@ __forceinline void Threading::Timeslice() sched_yield(); } -void Threading::PersistentThread::_pt_callback_cleanup( void* handle ) +void Threading::pxThread::_pt_callback_cleanup( void* handle ) { - ((PersistentThread*)handle)->_ThreadCleanup(); + ((pxThread*)handle)->_ThreadCleanup(); } -Threading::PersistentThread::PersistentThread() - : m_name( L"PersistentThread" ) +Threading::pxThread::pxThread() + : m_name( L"pxThread" ) { m_detached = true; // start out with m_thread in detached/invalid state m_running = false; @@ -166,12 +166,12 @@ Threading::PersistentThread::PersistentThread() // This destructor performs basic "last chance" cleanup, which is a blocking join // against the thread. Extending classes should almost always implement their own -// thread closure process, since any PersistentThread will, by design, not terminate +// thread closure process, since any pxThread will, by design, not terminate // unless it has been properly canceled (resulting in deadlock). // // Thread safety: This class must not be deleted from its own thread. That would be // like marrying your sister, and then cheating on her with your daughter. -Threading::PersistentThread::~PersistentThread() throw() +Threading::pxThread::~pxThread() throw() { try { @@ -188,7 +188,7 @@ Threading::PersistentThread::~PersistentThread() throw() DESTRUCTOR_CATCHALL } -bool Threading::PersistentThread::AffinityAssert_AllowFromSelf( const DiagnosticOrigin& origin ) const +bool Threading::pxThread::AffinityAssert_AllowFromSelf( const DiagnosticOrigin& origin ) const { if( IsSelf() ) return true; @@ -198,7 +198,7 @@ bool Threading::PersistentThread::AffinityAssert_AllowFromSelf( const Diagnostic return false; } -bool Threading::PersistentThread::AffinityAssert_DisallowFromSelf( const DiagnosticOrigin& origin ) const +bool Threading::pxThread::AffinityAssert_DisallowFromSelf( const DiagnosticOrigin& origin ) const { if( !IsSelf() ) return true; @@ -208,7 +208,7 @@ bool Threading::PersistentThread::AffinityAssert_DisallowFromSelf( const Diagnos return false; } -void Threading::PersistentThread::FrankenMutex( Mutex& mutex ) +void Threading::pxThread::FrankenMutex( Mutex& mutex ) { if( mutex.RecreateIfLocked() ) { @@ -227,7 +227,7 @@ void Threading::PersistentThread::FrankenMutex( Mutex& mutex ) // instead override DoPrepStart instead. // // This function should not be called from the owner thread. -void Threading::PersistentThread::Start() +void Threading::pxThread::Start() { // Prevents sudden parallel startup, and or parallel startup + cancel: ScopedLock startlock( m_lock_start ); @@ -267,7 +267,7 @@ void Threading::PersistentThread::Start() // Returns: TRUE if the detachment was performed, or FALSE if the thread was // already detached or isn't running at all. // This function should not be called from the owner thread. -bool Threading::PersistentThread::Detach() +bool Threading::pxThread::Detach() { AffinityAssert_DisallowFromSelf(pxDiagSpot); @@ -276,7 +276,7 @@ bool Threading::PersistentThread::Detach() return true; } -bool Threading::PersistentThread::_basecancel() +bool Threading::pxThread::_basecancel() { if( !m_running ) return false; @@ -291,7 +291,7 @@ bool Threading::PersistentThread::_basecancel() } // Remarks: -// Provision of non-blocking Cancel() is probably academic, since destroying a PersistentThread +// Provision of non-blocking Cancel() is probably academic, since destroying a pxThread // object performs a blocking Cancel regardless of if you explicitly do a non-blocking Cancel() // prior, since the ExecuteTaskInThread() method requires a valid object state. If you really need // fire-and-forget behavior on threads, use pthreads directly for now. @@ -304,7 +304,7 @@ bool Threading::PersistentThread::_basecancel() // Exceptions raised by the blocking thread will be re-thrown into the main thread. If isBlocking // is false then no exceptions will occur. // -void Threading::PersistentThread::Cancel( bool isBlocking ) +void Threading::pxThread::Cancel( bool isBlocking ) { AffinityAssert_DisallowFromSelf( pxDiagSpot ); @@ -320,7 +320,7 @@ void Threading::PersistentThread::Cancel( bool isBlocking ) } } -bool Threading::PersistentThread::Cancel( const wxTimeSpan& timespan ) +bool Threading::pxThread::Cancel( const wxTimeSpan& timespan ) { AffinityAssert_DisallowFromSelf( pxDiagSpot ); @@ -337,7 +337,7 @@ bool Threading::PersistentThread::Cancel( const wxTimeSpan& timespan ) // Blocks execution of the calling thread until this thread completes its task. The // caller should make sure to signal the thread to exit, or else blocking may deadlock the -// calling thread. Classes which extend PersistentThread should override this method +// calling thread. Classes which extend pxThread should override this method // and signal any necessary thread exit variables prior to blocking. // // Returns the return code of the thread. @@ -345,31 +345,31 @@ bool Threading::PersistentThread::Cancel( const wxTimeSpan& timespan ) // // Exceptions raised by the blocking thread will be re-thrown into the main thread. // -void Threading::PersistentThread::Block() +void Threading::pxThread::Block() { AffinityAssert_DisallowFromSelf(pxDiagSpot); WaitOnSelf( m_lock_InThread ); } -bool Threading::PersistentThread::Block( const wxTimeSpan& timeout ) +bool Threading::pxThread::Block( const wxTimeSpan& timeout ) { AffinityAssert_DisallowFromSelf(pxDiagSpot); return WaitOnSelf( m_lock_InThread, timeout ); } -bool Threading::PersistentThread::IsSelf() const +bool Threading::pxThread::IsSelf() const { // Detached threads may have their pthread handles recycled as newer threads, causing // false IsSelf reports. return !m_detached && (pthread_self() == m_thread); } -bool Threading::PersistentThread::IsRunning() const +bool Threading::pxThread::IsRunning() const { return !!m_running; } -void Threading::PersistentThread::AddListener( EventListener_Thread& evt ) +void Threading::pxThread::AddListener( EventListener_Thread& evt ) { evt.SetThread( this ); m_evtsrc_OnDelete.Add( evt ); @@ -378,13 +378,13 @@ void Threading::PersistentThread::AddListener( EventListener_Thread& evt ) // Throws an exception if the thread encountered one. Uses the BaseException's Rethrow() method, // which ensures the exception type remains consistent. Debuggable stacktraces will be lost, since // the thread will have allowed itself to terminate properly. -void Threading::PersistentThread::RethrowException() const +void Threading::pxThread::RethrowException() const { // Thread safety note: always detach the m_except pointer. If we checked it for NULL, the // pointer might still be invalid after detachment, so might as well just detach and check // after. - ScopedPtr ptr( const_cast(this)->m_except.DetachPtr() ); + ScopedPtr ptr( const_cast(this)->m_except.DetachPtr() ); if( ptr ) ptr->Rethrow(); //m_except->Rethrow(); @@ -405,7 +405,7 @@ void Threading::YieldToMain() m_BlockDeletions = false; } -void Threading::PersistentThread::_selfRunningTest( const wxChar* name ) const +void Threading::pxThread::_selfRunningTest( const wxChar* name ) const { if( HasPendingException() ) { @@ -424,14 +424,14 @@ void Threading::PersistentThread::_selfRunningTest( const wxChar* name ) const } // Thread is still alive and kicking (for now) -- yield to other messages and hope - // that impending chaos does not ensue. [it shouldn't since we block PersistentThread + // that impending chaos does not ensue. [it shouldn't since we block pxThread // objects from being deleted until outside the scope of a mutex/semaphore wait). if( (wxTheApp != NULL) && wxThread::IsMain() && !_WaitGui_RecursionGuard( L"WaitForSelf" ) ) Threading::YieldToMain(); } -// This helper function is a deadlock-safe method of waiting on a semaphore in a PersistentThread. If the +// This helper function is a deadlock-safe method of waiting on a semaphore in a pxThread. If the // thread is terminated or canceled by another thread or a nested action prior to the semaphore being // posted, this function will detect that and throw a CancelEvent exception is thrown. // @@ -442,7 +442,7 @@ void Threading::PersistentThread::_selfRunningTest( const wxChar* name ) const // This function will rethrow exceptions raised by the persistent thread, if it throws an error // while the calling thread is blocking (which also means the persistent thread has terminated). // -void Threading::PersistentThread::WaitOnSelf( Semaphore& sem ) const +void Threading::pxThread::WaitOnSelf( Semaphore& sem ) const { if( !AffinityAssert_DisallowFromSelf(pxDiagSpot) ) return; @@ -453,7 +453,7 @@ void Threading::PersistentThread::WaitOnSelf( Semaphore& sem ) const } } -// This helper function is a deadlock-safe method of waiting on a mutex in a PersistentThread. +// This helper function is a deadlock-safe method of waiting on a mutex in a pxThread. // If the thread is terminated or canceled by another thread or a nested action prior to the // mutex being unlocked, this function will detect that and a CancelEvent exception is thrown. // @@ -466,7 +466,7 @@ void Threading::PersistentThread::WaitOnSelf( Semaphore& sem ) const // error while the calling thread is blocking (which also means the persistent thread has // terminated). // -void Threading::PersistentThread::WaitOnSelf( Mutex& mutex ) const +void Threading::pxThread::WaitOnSelf( Mutex& mutex ) const { if( !AffinityAssert_DisallowFromSelf(pxDiagSpot) ) return; @@ -479,7 +479,7 @@ void Threading::PersistentThread::WaitOnSelf( Mutex& mutex ) const static const wxTimeSpan SelfWaitInterval( 0,0,0,333 ); -bool Threading::PersistentThread::WaitOnSelf( Semaphore& sem, const wxTimeSpan& timeout ) const +bool Threading::pxThread::WaitOnSelf( Semaphore& sem, const wxTimeSpan& timeout ) const { if( !AffinityAssert_DisallowFromSelf(pxDiagSpot) ) return true; @@ -495,7 +495,7 @@ bool Threading::PersistentThread::WaitOnSelf( Semaphore& sem, const wxTimeSpan& return false; } -bool Threading::PersistentThread::WaitOnSelf( Mutex& mutex, const wxTimeSpan& timeout ) const +bool Threading::pxThread::WaitOnSelf( Mutex& mutex, const wxTimeSpan& timeout ) const { if( !AffinityAssert_DisallowFromSelf(pxDiagSpot) ) return true; @@ -515,14 +515,14 @@ bool Threading::PersistentThread::WaitOnSelf( Mutex& mutex, const wxTimeSpan& ti // function will throw an SEH exception designed to exit the thread (so make sure to use C++ // object encapsulation for anything that could leak resources, to ensure object unwinding // and cleanup, or use the DoThreadCleanup() override to perform resource cleanup). -void Threading::PersistentThread::TestCancel() const +void Threading::pxThread::TestCancel() const { AffinityAssert_AllowFromSelf(pxDiagSpot); pthread_testcancel(); } // Executes the virtual member method -void Threading::PersistentThread::_try_virtual_invoke( void (PersistentThread::*method)() ) +void Threading::pxThread::_try_virtual_invoke( void (pxThread::*method)() ) { try { (this->*method)(); @@ -574,10 +574,10 @@ void Threading::PersistentThread::_try_virtual_invoke( void (PersistentThread::* // invoked internally when canceling or exiting the thread. Extending classes should implement // OnCleanupInThread() to extend cleanup functionality. -void Threading::PersistentThread::_ThreadCleanup() +void Threading::pxThread::_ThreadCleanup() { AffinityAssert_AllowFromSelf(pxDiagSpot); - _try_virtual_invoke( &PersistentThread::OnCleanupInThread ); + _try_virtual_invoke( &pxThread::OnCleanupInThread ); m_lock_InThread.Release(); // Must set m_running LAST, as thread destructors depend on this value (it is used @@ -585,7 +585,7 @@ void Threading::PersistentThread::_ThreadCleanup() m_running = false; } -wxString Threading::PersistentThread::GetName() const +wxString Threading::pxThread::GetName() const { return m_name; } @@ -597,7 +597,7 @@ wxString Threading::PersistentThread::GetName() const // worry that the calling thread might attempt to test the status of those variables // before initialization has completed. // -void Threading::PersistentThread::OnStartInThread() +void Threading::pxThread::OnStartInThread() { m_detached = false; m_running = true; @@ -605,7 +605,7 @@ void Threading::PersistentThread::OnStartInThread() _platform_specific_OnStartInThread(); } -void Threading::PersistentThread::_internal_execute() +void Threading::pxThread::_internal_execute() { m_lock_InThread.Acquire(); @@ -617,12 +617,12 @@ void Threading::PersistentThread::_internal_execute() OnStartInThread(); m_sem_startup.Post(); - _try_virtual_invoke( &PersistentThread::ExecuteTaskInThread ); + _try_virtual_invoke( &pxThread::ExecuteTaskInThread ); } // Called by Start, prior to actual starting of the thread, and after any previous // running thread has been canceled or detached. -void Threading::PersistentThread::OnStart() +void Threading::pxThread::OnStart() { m_native_handle = NULL; m_native_id = 0; @@ -634,7 +634,7 @@ void Threading::PersistentThread::OnStart() // Extending classes that override this method should always call it last from their // personal implementations. -void Threading::PersistentThread::OnCleanupInThread() +void Threading::pxThread::OnCleanupInThread() { if( curthread_key != NULL ) pthread_setspecific( curthread_key, NULL ); @@ -651,10 +651,10 @@ void Threading::PersistentThread::OnCleanupInThread() // passed into pthread_create, and is used to dispatch the thread's object oriented // callback function -void* Threading::PersistentThread::_internal_callback( void* itsme ) +void* Threading::pxThread::_internal_callback( void* itsme ) { if( !pxAssertDev( itsme != NULL, wxNullChar ) ) return NULL; - PersistentThread& owner = *((PersistentThread*)itsme); + pxThread& owner = *((pxThread*)itsme); pthread_cleanup_push( _pt_callback_cleanup, itsme ); owner._internal_execute(); @@ -662,7 +662,7 @@ void* Threading::PersistentThread::_internal_callback( void* itsme ) return NULL; } -void Threading::PersistentThread::_DoSetThreadName( const wxString& name ) +void Threading::pxThread::_DoSetThreadName( const wxString& name ) { _DoSetThreadName( name.ToUTF8() ); } @@ -677,7 +677,7 @@ void Threading::BaseTaskThread::Block() if( !IsRunning() ) return; m_Done = true; m_sem_event.Post(); - PersistentThread::Block(); + pxThread::Block(); } // Initiates the new task. This should be called after your own StartTask has @@ -845,12 +845,12 @@ wxString Exception::BaseThreadError::FormatDisplayMessage() const return wxsFormat( m_message_user, (m_thread==NULL) ? L"Null Thread Object" : m_thread->GetName().c_str()); } -PersistentThread& Exception::BaseThreadError::Thread() +pxThread& Exception::BaseThreadError::Thread() { pxAssertDev( m_thread != NULL, "NULL thread object on ThreadError exception." ); return *m_thread; } -const PersistentThread& Exception::BaseThreadError::Thread() const +const pxThread& Exception::BaseThreadError::Thread() const { pxAssertDev( m_thread != NULL, "NULL thread object on ThreadError exception." ); return *m_thread; diff --git a/common/src/Utilities/Windows/WinThreads.cpp b/common/src/Utilities/Windows/WinThreads.cpp index bdcd9ee500..0133f89e38 100644 --- a/common/src/Utilities/Windows/WinThreads.cpp +++ b/common/src/Utilities/Windows/WinThreads.cpp @@ -73,7 +73,7 @@ u64 Threading::GetThreadTicksPerSecond() return 10000000; } -u64 Threading::PersistentThread::GetCpuTime() const +u64 Threading::pxThread::GetCpuTime() const { if( m_native_handle == NULL ) return 0; @@ -86,7 +86,7 @@ u64 Threading::PersistentThread::GetCpuTime() const return 0; // thread prolly doesn't exist anymore. } -void Threading::PersistentThread::_platform_specific_OnStartInThread() +void Threading::pxThread::_platform_specific_OnStartInThread() { // OpenThread Note: Vista and Win7 need only THREAD_QUERY_LIMITED_INFORMATION (XP and 2k need more), // however we own our process threads, so shouldn't matter in any case... @@ -97,12 +97,12 @@ void Threading::PersistentThread::_platform_specific_OnStartInThread() pxAssertDev( m_native_handle != NULL, wxNullChar ); } -void Threading::PersistentThread::_platform_specific_OnCleanupInThread() +void Threading::pxThread::_platform_specific_OnCleanupInThread() { CloseHandle( (HANDLE)m_native_handle ); } -void Threading::PersistentThread::_DoSetThreadName( const char* name ) +void Threading::pxThread::_DoSetThreadName( const char* name ) { // This feature needs Windows headers and MSVC's SEH support: diff --git a/common/src/Utilities/wxAppWithHelpers.cpp b/common/src/Utilities/wxAppWithHelpers.cpp index d0b242ea42..283491655f 100644 --- a/common/src/Utilities/wxAppWithHelpers.cpp +++ b/common/src/Utilities/wxAppWithHelpers.cpp @@ -103,35 +103,35 @@ void SynchronousActionState::PostResult() } // -------------------------------------------------------------------------------------- -// pxInvokeActionEvent Implementations +// pxActionEvent Implementations // -------------------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS( pxInvokeActionEvent, wxEvent ) +IMPLEMENT_DYNAMIC_CLASS( pxActionEvent, wxEvent ) -pxInvokeActionEvent::pxInvokeActionEvent( SynchronousActionState* sema, int msgtype ) +pxActionEvent::pxActionEvent( SynchronousActionState* sema, int msgtype ) : wxEvent( 0, msgtype ) { m_state = sema; } -pxInvokeActionEvent::pxInvokeActionEvent( SynchronousActionState& sema, int msgtype ) +pxActionEvent::pxActionEvent( SynchronousActionState& sema, int msgtype ) : wxEvent( 0, msgtype ) { m_state = &sema; } -pxInvokeActionEvent::pxInvokeActionEvent( const pxInvokeActionEvent& src ) +pxActionEvent::pxActionEvent( const pxActionEvent& src ) : wxEvent( src ) { m_state = src.m_state; } -void pxInvokeActionEvent::SetException( const BaseException& ex ) +void pxActionEvent::SetException( const BaseException& ex ) { SetException( ex.Clone() ); } -void pxInvokeActionEvent::SetException( BaseException* ex ) +void pxActionEvent::SetException( BaseException* ex ) { const wxString& prefix( wxsFormat(L"(%s) ", GetClassInfo()->GetClassName()) ); ex->DiagMsg() = prefix + ex->DiagMsg(); @@ -205,39 +205,39 @@ void pxSynchronousCommandEvent::SetException( BaseException* ex ) } // -------------------------------------------------------------------------------------- -// pxInvokeMethodEvent +// pxRpcEvent // -------------------------------------------------------------------------------------- // Unlike pxPingEvent, the Semaphore belonging to this event is typically posted when the // invoked method is completed. If the method can be executed in non-blocking fashion then // it should leave the semaphore postback NULL. // -class pxInvokeMethodEvent : public pxInvokeActionEvent +class pxRpcEvent : public pxActionEvent { - DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxInvokeMethodEvent) + DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxRpcEvent) - typedef pxInvokeActionEvent _parent; + typedef pxActionEvent _parent; protected: void (*m_Method)(); public: - virtual ~pxInvokeMethodEvent() throw() { } - virtual pxInvokeMethodEvent *Clone() const { return new pxInvokeMethodEvent(*this); } + virtual ~pxRpcEvent() throw() { } + virtual pxRpcEvent *Clone() const { return new pxRpcEvent(*this); } - explicit pxInvokeMethodEvent( void (*method)()=NULL, SynchronousActionState* sema=NULL ) - : pxInvokeActionEvent( sema ) + explicit pxRpcEvent( void (*method)()=NULL, SynchronousActionState* sema=NULL ) + : pxActionEvent( sema ) { m_Method = method; } - explicit pxInvokeMethodEvent( void (*method)(), SynchronousActionState& sema ) - : pxInvokeActionEvent( sema ) + explicit pxRpcEvent( void (*method)(), SynchronousActionState& sema ) + : pxActionEvent( sema ) { m_Method = method; } - pxInvokeMethodEvent( const pxInvokeMethodEvent& src ) - : pxInvokeActionEvent( src ) + pxRpcEvent( const pxRpcEvent& src ) + : pxActionEvent( src ) { m_Method = src.m_Method; } @@ -254,7 +254,7 @@ protected: } }; -IMPLEMENT_DYNAMIC_CLASS( pxInvokeMethodEvent, pxInvokeActionEvent ) +IMPLEMENT_DYNAMIC_CLASS( pxRpcEvent, pxActionEvent ) // -------------------------------------------------------------------------------------- // pxExceptionEvent implementations @@ -285,25 +285,59 @@ IMPLEMENT_DYNAMIC_CLASS( wxAppWithHelpers, wxApp ) // main thread. void wxAppWithHelpers::PostMethod( FnType_Void* method ) { - PostEvent( pxInvokeMethodEvent( method ) ); + PostEvent( pxRpcEvent( method ) ); } // Posts a method to the main thread; non-blocking. Post occurs even when called from the // main thread. void wxAppWithHelpers::PostIdleMethod( FnType_Void* method ) { - pxInvokeMethodEvent evt( method ); + pxRpcEvent evt( method ); AddIdleEvent( evt ); } -bool wxAppWithHelpers::PostMethodMyself( void (*method)() ) +// Invokes the specified void method, or posts the method to the main thread if the calling +// thread is not Main. Action is blocking. For non-blocking method execution, use +// AppRpc_TryInvokeAsync. +// +// This function works something like setjmp/longjmp, in that the return value indicates if the +// function actually executed the specified method or not. +// +// Returns: +// FALSE if the method was not invoked (meaning this IS the main thread!) +// TRUE if the method was invoked. +// + +bool wxAppWithHelpers::Rpc_TryInvoke( FnType_Void* method ) { if( wxThread::IsMain() ) return false; - PostEvent( pxInvokeMethodEvent( method ) ); + + SynchronousActionState sync; + PostEvent( pxRpcEvent( method, sync ) ); + sync.WaitForResult(); + return true; } -void wxAppWithHelpers::ProcessMethod( void (*method)() ) +// Invokes the specified void method, or posts the method to the main thread if the calling +// thread is not Main. Action is non-blocking (asynchronous). For blocking method execution, +// use AppRpc_TryInvoke. +// +// This function works something like setjmp/longjmp, in that the return value indicates if the +// function actually executed the specified method or not. +// +// Returns: +// FALSE if the method was not posted to the main thread (meaning this IS the main thread!) +// TRUE if the method was posted. +// +bool wxAppWithHelpers::Rpc_TryInvokeAsync( FnType_Void* method ) +{ + if( wxThread::IsMain() ) return false; + PostEvent( pxRpcEvent( method ) ); + return true; +} + +void wxAppWithHelpers::ProcessMethod( FnType_Void* method ) { if( wxThread::IsMain() ) { @@ -312,7 +346,7 @@ void wxAppWithHelpers::ProcessMethod( void (*method)() ) } SynchronousActionState sync; - PostEvent( pxInvokeMethodEvent( method, sync ) ); + PostEvent( pxRpcEvent( method, sync ) ); sync.WaitForResult(); } @@ -345,7 +379,7 @@ bool wxAppWithHelpers::ProcessEvent( wxEvent* evt ) return _parent::ProcessEvent( *deleteMe ); } -bool wxAppWithHelpers::ProcessEvent( pxInvokeActionEvent& evt ) +bool wxAppWithHelpers::ProcessEvent( pxActionEvent& evt ) { if( wxThread::IsMain() ) return _parent::ProcessEvent( evt ); @@ -359,7 +393,7 @@ bool wxAppWithHelpers::ProcessEvent( pxInvokeActionEvent& evt ) } } -bool wxAppWithHelpers::ProcessEvent( pxInvokeActionEvent* evt ) +bool wxAppWithHelpers::ProcessEvent( pxActionEvent* evt ) { if( wxThread::IsMain() ) { @@ -389,7 +423,11 @@ void wxAppWithHelpers::CleanUp() _parent::CleanUp(); } -void pxInvokeActionEvent::_DoInvokeEvent() +// Executes the event with exception handling. If the event throws an exception, the exception +// will be neatly packaged and transported back to the thread that posted the event. +// This function is virtual, however overloading it is not recommended. Derrived classes +// should overload InvokeEvent() instead. +void pxActionEvent::_DoInvokeEvent() { AffinityAssert_AllowFrom_MainUI(); @@ -497,7 +535,7 @@ void wxAppWithHelpers::Ping() DbgCon.WriteLn( Color_Gray, L"App Event Ping Requested from %s thread.", pxGetCurrentThreadName().c_str() ); SynchronousActionState sync; - pxInvokeActionEvent evt( sync ); + pxActionEvent evt( sync ); AddIdleEvent( evt ); sync.WaitForResult(); } @@ -537,12 +575,12 @@ sptr wxAppWithHelpers::ProcessCommand( int evtType, int intParam, long longParam return ProcessCommand( NULL, evtType, intParam, longParam, stringParam ); } -void wxAppWithHelpers::PostAction( const pxInvokeActionEvent& evt ) +void wxAppWithHelpers::PostAction( const pxActionEvent& evt ) { PostEvent( evt ); } -void wxAppWithHelpers::ProcessAction( pxInvokeActionEvent& evt ) +void wxAppWithHelpers::ProcessAction( pxActionEvent& evt ) { if( !wxThread::IsMain() ) { @@ -564,7 +602,7 @@ void wxAppWithHelpers::DeleteObject( BaseDeletableObject& obj ) AddIdleEvent( evt ); } -void wxAppWithHelpers::DeleteThread( PersistentThread& obj ) +void wxAppWithHelpers::DeleteThread( pxThread& obj ) { //pxAssume( obj.IsBeingDeleted() ); wxCommandEvent evt( pxEvt_DeleteThread ); @@ -572,7 +610,7 @@ void wxAppWithHelpers::DeleteThread( PersistentThread& obj ) AddIdleEvent( evt ); } -typedef void (wxEvtHandler::*pxInvokeActionEventFunction)(pxInvokeActionEvent&); +typedef void (wxEvtHandler::*pxInvokeActionEventFunction)(pxActionEvent&); bool wxAppWithHelpers::OnInit() { @@ -594,7 +632,7 @@ bool wxAppWithHelpers::OnInit() return _parent::OnInit(); } -void wxAppWithHelpers::OnInvokeAction( pxInvokeActionEvent& evt ) +void wxAppWithHelpers::OnInvokeAction( pxActionEvent& evt ) { evt._DoInvokeEvent(); // wow this is easy! } @@ -609,7 +647,7 @@ void wxAppWithHelpers::OnDeleteObject( wxCommandEvent& evt ) // (thus we have a fairly automatic threaded exception system!) void wxAppWithHelpers::OnDeleteThread( wxCommandEvent& evt ) { - ScopedPtr thr( (PersistentThread*)evt.GetClientData() ); + ScopedPtr thr( (pxThread*)evt.GetClientData() ); if( !thr ) return; thr->RethrowException(); diff --git a/pcsx2/System/SysThreads.h b/pcsx2/System/SysThreads.h index aa673c0e08..427058d174 100644 --- a/pcsx2/System/SysThreads.h +++ b/pcsx2/System/SysThreads.h @@ -29,9 +29,9 @@ typedef SafeArray VmStateBuffer; // SysThreadBase // -------------------------------------------------------------------------------------- -class SysThreadBase : public PersistentThread +class SysThreadBase : public pxThread { - typedef PersistentThread _parent; + typedef pxThread _parent; public: // Important: The order of these enumerations matters! Optimized tests are used for both diff --git a/pcsx2/ZipTools/ThreadedZipTools.h b/pcsx2/ZipTools/ThreadedZipTools.h index d8f79cebda..d9ec6c80d3 100644 --- a/pcsx2/ZipTools/ThreadedZipTools.h +++ b/pcsx2/ZipTools/ThreadedZipTools.h @@ -57,10 +57,10 @@ typedef void FnType_ReadCompressedHeader( IStreamReader& thr ); // BaseCompressThread // -------------------------------------------------------------------------------------- class BaseCompressThread - : public PersistentThread + : public pxThread , public IStreamWriter { - typedef PersistentThread _parent; + typedef pxThread _parent; protected: FnType_WriteCompressedHeader* m_WriteHeaderInThread; diff --git a/pcsx2/gui/App.h b/pcsx2/gui/App.h index 8b15a691fc..1ea07b9e68 100644 --- a/pcsx2/gui/App.h +++ b/pcsx2/gui/App.h @@ -654,8 +654,8 @@ public: void OnProgramLogClosed( wxWindowID id ); protected: - bool InvokeOnMainThread( FnPtr_Pcsx2App method ); - bool PostAppMethodMyself( FnPtr_Pcsx2App method ); + bool AppRpc_TryInvoke( FnPtr_Pcsx2App method ); + bool AppRpc_TryInvokeAsync( FnPtr_Pcsx2App method ); void AllocateCoreStuffs(); void InitDefaultGlobalAccelerators(); diff --git a/pcsx2/gui/AppCorePlugins.cpp b/pcsx2/gui/AppCorePlugins.cpp index 7f8ae5d112..730420751a 100644 --- a/pcsx2/gui/AppCorePlugins.cpp +++ b/pcsx2/gui/AppCorePlugins.cpp @@ -43,9 +43,9 @@ PluginManager& GetCorePlugins() // -------------------------------------------------------------------------------------- // CorePluginsEvent // -------------------------------------------------------------------------------------- -class CorePluginsEvent : public pxInvokeActionEvent +class CorePluginsEvent : public pxActionEvent { - typedef pxInvokeActionEvent _parent; + typedef pxActionEvent _parent; protected: PluginEventType m_evt; @@ -55,19 +55,19 @@ public: CorePluginsEvent* Clone() const { return new CorePluginsEvent( *this ); } explicit CorePluginsEvent( PluginEventType evt, SynchronousActionState* sema=NULL ) - : pxInvokeActionEvent( sema ) + : pxActionEvent( sema ) { m_evt = evt; } explicit CorePluginsEvent( PluginEventType evt, SynchronousActionState& sema ) - : pxInvokeActionEvent( sema ) + : pxActionEvent( sema ) { m_evt = evt; } CorePluginsEvent( const CorePluginsEvent& src ) - : pxInvokeActionEvent( src ) + : pxActionEvent( src ) { m_evt = src.m_evt; } @@ -128,9 +128,9 @@ protected: // -------------------------------------------------------------------------------------- // LoadSinglePluginEvent // -------------------------------------------------------------------------------------- -class LoadSinglePluginEvent : public pxInvokeActionEvent +class LoadSinglePluginEvent : public pxActionEvent { - typedef pxInvokeActionEvent _parent; + typedef pxActionEvent _parent; DECLARE_DYNAMIC_CLASS_NO_ASSIGN(LoadSinglePluginEvent) protected: @@ -154,9 +154,9 @@ protected: } }; -class SinglePluginMethodEvent : public pxInvokeActionEvent +class SinglePluginMethodEvent : public pxActionEvent { - typedef pxInvokeActionEvent _parent; + typedef pxActionEvent _parent; DECLARE_DYNAMIC_CLASS_NO_ASSIGN(SinglePluginMethodEvent) protected: @@ -181,8 +181,8 @@ protected: } }; -IMPLEMENT_DYNAMIC_CLASS( LoadSinglePluginEvent, pxInvokeActionEvent ); -IMPLEMENT_DYNAMIC_CLASS( SinglePluginMethodEvent, pxInvokeActionEvent ); +IMPLEMENT_DYNAMIC_CLASS( LoadSinglePluginEvent, pxActionEvent ); +IMPLEMENT_DYNAMIC_CLASS( SinglePluginMethodEvent, pxActionEvent ); // -------------------------------------------------------------------------------------- // AppPluginManager diff --git a/pcsx2/gui/AppCoreThread.cpp b/pcsx2/gui/AppCoreThread.cpp index c2bc142213..7db7b79cf5 100644 --- a/pcsx2/gui/AppCoreThread.cpp +++ b/pcsx2/gui/AppCoreThread.cpp @@ -150,7 +150,7 @@ void AppCoreThread::ChangeCdvdSource() void Pcsx2App::SysApplySettings() { - if( InvokeOnMainThread(&Pcsx2App::SysApplySettings) ) return; + if( AppRpc_TryInvoke(&Pcsx2App::SysApplySettings) ) return; CoreThread.ApplySettings( g_Conf->EmuOptions ); CDVD_SourceType cdvdsrc( g_Conf->CdvdSource ); diff --git a/pcsx2/gui/AppEventListeners.h b/pcsx2/gui/AppEventListeners.h index 0ea253aabf..54d5021f7c 100644 --- a/pcsx2/gui/AppEventListeners.h +++ b/pcsx2/gui/AppEventListeners.h @@ -248,9 +248,9 @@ protected: // -------------------------------------------------------------------------------------- // CoreThreadStatusEvent // -------------------------------------------------------------------------------------- -class CoreThreadStatusEvent : public pxInvokeActionEvent +class CoreThreadStatusEvent : public pxActionEvent { - typedef pxInvokeActionEvent _parent; + typedef pxActionEvent _parent; protected: CoreThreadStatus m_evt; diff --git a/pcsx2/gui/AppEventSources.cpp b/pcsx2/gui/AppEventSources.cpp index 62539020fb..d58fa38ad1 100644 --- a/pcsx2/gui/AppEventSources.cpp +++ b/pcsx2/gui/AppEventSources.cpp @@ -157,13 +157,13 @@ void Pcsx2App::DispatchEvent( IniInterface& ini ) // CoreThreadStatusEvent Implementations // -------------------------------------------------------------------------------------- CoreThreadStatusEvent::CoreThreadStatusEvent( CoreThreadStatus evt, SynchronousActionState* sema ) - : pxInvokeActionEvent( sema ) + : pxActionEvent( sema ) { m_evt = evt; } CoreThreadStatusEvent::CoreThreadStatusEvent( CoreThreadStatus evt, SynchronousActionState& sema ) - : pxInvokeActionEvent( sema ) + : pxActionEvent( sema ) { m_evt = evt; } diff --git a/pcsx2/gui/AppInit.cpp b/pcsx2/gui/AppInit.cpp index 1433fb289a..2149352eb7 100644 --- a/pcsx2/gui/AppInit.cpp +++ b/pcsx2/gui/AppInit.cpp @@ -181,6 +181,8 @@ void Pcsx2App::ReadUserModeSettings() void Pcsx2App::DetectCpuAndUserMode() { + AffinityAssert_AllowFrom_MainUI(); + x86caps.Identify(); x86caps.CountCores(); x86caps.SIMD_EstablishMXCSRmask(); @@ -198,6 +200,8 @@ void Pcsx2App::DetectCpuAndUserMode() void Pcsx2App::OpenMainFrame() { + if( AppRpc_TryInvokeAsync( &Pcsx2App::OpenMainFrame ) ) return; + if( GetMainFramePtr() != NULL ) return; MainEmuFrame* mainFrame = new MainEmuFrame( NULL, L"PCSX2" ); @@ -212,6 +216,8 @@ void Pcsx2App::OpenMainFrame() void Pcsx2App::OpenProgramLog() { + if( AppRpc_TryInvokeAsync( &Pcsx2App::OpenProgramLog ) ) return; + if( ConsoleLogFrame* frame = GetProgramLog() ) { //pxAssume( ); @@ -230,12 +236,17 @@ void Pcsx2App::OpenProgramLog() void Pcsx2App::AllocateCoreStuffs() { + if( AppRpc_TryInvokeAsync( &Pcsx2App::OpenMainFrame ) ) return; + CpuCheckSSE2(); SysLogMachineCaps(); AppApplySettings(); if( !m_CoreAllocs ) { + // FIXME : Some or all of SysCoreAllocations should be run from the SysExecutor thread, + // so that the thread is safely blocked from being able to start emulation. + m_CoreAllocs = new SysCoreAllocations(); if( m_CoreAllocs->HadSomeFailures( g_Conf->EmuOptions.Cpu.Recompiler ) ) @@ -511,12 +522,11 @@ bool Pcsx2App::OnInit() // Start GUI and/or Direct Emulation // ------------------------------------- if( Startup.ForceConsole ) g_Conf->ProgLogBox.Visible = true; - PostAppMethod( &Pcsx2App::OpenProgramLog ); + OpenProgramLog(); - if( m_UseGUI ) - PostAppMethod( &Pcsx2App::OpenMainFrame ); + if( m_UseGUI ) OpenMainFrame(); - PostAppMethod( &Pcsx2App::AllocateCoreStuffs ); + AllocateCoreStuffs(); } // ---------------------------------------------------------------------------- catch( Exception::StartupAborted& ex ) // user-aborted, no popups needed. diff --git a/pcsx2/gui/AppMain.cpp b/pcsx2/gui/AppMain.cpp index 6a538452fd..8695b14236 100644 --- a/pcsx2/gui/AppMain.cpp +++ b/pcsx2/gui/AppMain.cpp @@ -171,9 +171,9 @@ void Pcsx2App::PostMenuAction( MenuIdentifiers menu_id ) const // invoked method is completed. If the method can be executed in non-blocking fashion then // it should leave the semaphore postback NULL. // -class Pcsx2AppMethodEvent : public pxInvokeActionEvent +class Pcsx2AppMethodEvent : public pxActionEvent { - typedef pxInvokeActionEvent _parent; + typedef pxActionEvent _parent; DECLARE_DYNAMIC_CLASS_NO_ASSIGN(Pcsx2AppMethodEvent) protected: @@ -184,19 +184,19 @@ public: virtual Pcsx2AppMethodEvent *Clone() const { return new Pcsx2AppMethodEvent(*this); } explicit Pcsx2AppMethodEvent( FnPtr_Pcsx2App method=NULL, SynchronousActionState* sema=NULL ) - : pxInvokeActionEvent( sema ) + : pxActionEvent( sema ) { m_Method = method; } explicit Pcsx2AppMethodEvent( FnPtr_Pcsx2App method, SynchronousActionState& sema ) - : pxInvokeActionEvent( sema ) + : pxActionEvent( sema ) { m_Method = method; } Pcsx2AppMethodEvent( const Pcsx2AppMethodEvent& src ) - : pxInvokeActionEvent( src ) + : pxActionEvent( src ) { m_Method = src.m_Method; } @@ -214,7 +214,7 @@ protected: }; -IMPLEMENT_DYNAMIC_CLASS( Pcsx2AppMethodEvent, pxInvokeActionEvent ) +IMPLEMENT_DYNAMIC_CLASS( Pcsx2AppMethodEvent, pxActionEvent ) #ifdef __WXGTK__ extern int TranslateGDKtoWXK( u32 keysym ); @@ -307,7 +307,7 @@ double FramerateManager::GetFramerate() const // times a second if not (ok, not quite, but you get the idea... I hope.) void Pcsx2App::LogicalVsync() { - if( PostAppMethodMyself( &Pcsx2App::LogicalVsync ) ) return; + if( AppRpc_TryInvokeAsync( &Pcsx2App::LogicalVsync ) ) return; if( !SysHasValidState() ) return; @@ -491,7 +491,7 @@ void Pcsx2App::HandleEvent(wxEvtHandler* handler, wxEventFunction func, wxEvent& // should be matched by a call to ClearPendingSave(). void Pcsx2App::StartPendingSave() { - if( PostAppMethodMyself(&Pcsx2App::StartPendingSave) ) return; + if( AppRpc_TryInvokeAsync(&Pcsx2App::StartPendingSave) ) return; ++m_PendingSaves; } @@ -500,7 +500,7 @@ void Pcsx2App::StartPendingSave() // such calls are detected (though the detection is far from fool-proof). void Pcsx2App::ClearPendingSave() { - if( PostAppMethodMyself(&Pcsx2App::ClearPendingSave) ) return; + if( AppRpc_TryInvokeAsync(&Pcsx2App::ClearPendingSave) ) return; --m_PendingSaves; pxAssumeDev( m_PendingSaves >= 0, "Pending saves count mismatch (pending count is less than 0)" ); @@ -659,7 +659,7 @@ AppIniLoader::AppIniLoader() void AppLoadSettings() { - if( wxGetApp().PostMethodMyself(AppLoadSettings) ) return; + if( wxGetApp().Rpc_TryInvoke(AppLoadSettings) ) return; AppIniLoader loader; g_Conf->LoadSave( loader ); @@ -672,7 +672,7 @@ void AppLoadSettings() void AppSaveSettings() { - if( wxGetApp().PostMethodMyself(AppSaveSettings) ) return; + if( wxGetApp().Rpc_TryInvokeAsync(AppSaveSettings) ) return; if( !wxFile::Exists( g_Conf->CurrentIso ) ) g_Conf->CurrentIso.clear(); @@ -686,7 +686,7 @@ void AppSaveSettings() // Invokes the specified Pcsx2App method, or posts the method to the main thread if the calling // thread is not Main. Action is blocking. For non-blocking method execution, use -// PostAppMethodMyself. +// AppRpc_TryInvokeAsync. // // This function works something like setjmp/longjmp, in that the return value indicates if the // function actually executed the specified method or not. @@ -695,7 +695,7 @@ void AppSaveSettings() // FALSE if the method was not posted to the main thread (meaning this IS the main thread!) // TRUE if the method was posted. // -bool Pcsx2App::InvokeOnMainThread( FnPtr_Pcsx2App method ) +bool Pcsx2App::AppRpc_TryInvoke( FnPtr_Pcsx2App method ) { if( wxThread::IsMain() ) return false; @@ -708,7 +708,7 @@ bool Pcsx2App::InvokeOnMainThread( FnPtr_Pcsx2App method ) // Invokes the specified Pcsx2App method, or posts the method to the main thread if the calling // thread is not Main. Action is non-blocking. For blocking method execution, use -// InvokeOnMainThread. +// AppRpc_TryInvoke. // // This function works something like setjmp/longjmp, in that the return value indicates if the // function actually executed the specified method or not. @@ -717,7 +717,7 @@ bool Pcsx2App::InvokeOnMainThread( FnPtr_Pcsx2App method ) // FALSE if the method was not posted to the main thread (meaning this IS the main thread!) // TRUE if the method was posted. // -bool Pcsx2App::PostAppMethodMyself( FnPtr_Pcsx2App method ) +bool Pcsx2App::AppRpc_TryInvokeAsync( FnPtr_Pcsx2App method ) { if( wxThread::IsMain() ) return false; PostEvent( Pcsx2AppMethodEvent( method ) ); @@ -741,7 +741,7 @@ void Pcsx2App::PostIdleAppMethod( FnPtr_Pcsx2App method ) void Pcsx2App::OpenGsPanel() { - if( InvokeOnMainThread( &Pcsx2App::OpenGsPanel ) ) return; + if( AppRpc_TryInvoke( &Pcsx2App::OpenGsPanel ) ) return; GSFrame* gsFrame = GetGsFramePtr(); if( gsFrame == NULL ) @@ -760,6 +760,9 @@ void Pcsx2App::OpenGsPanel() // Doing an immediate hide/show didn't work. So now I'm trying a resize. Because // wxWidgets is "clever" (grr!) it optimizes out just force-setting the same size // over again, so instead I resize it to size-1 and then back to the original size. + // + // FIXME: Gsdx memory leaks in DX10 have been fixed. This code may not be needed + // anymore. const wxSize oldsize( gsFrame->GetSize() ); wxSize newsize( oldsize ); @@ -780,7 +783,7 @@ void Pcsx2App::OpenGsPanel() void Pcsx2App::CloseGsPanel() { - if( InvokeOnMainThread( &Pcsx2App::CloseGsPanel ) ) return; + if( AppRpc_TryInvoke( &Pcsx2App::CloseGsPanel ) ) return; GSFrame* gsFrame = GetGsFramePtr(); if( (gsFrame != NULL) && CloseViewportWithPlugins ) diff --git a/pcsx2/gui/ConsoleLogger.h b/pcsx2/gui/ConsoleLogger.h index f19077d230..0aa5a1e6e8 100644 --- a/pcsx2/gui/ConsoleLogger.h +++ b/pcsx2/gui/ConsoleLogger.h @@ -66,9 +66,9 @@ protected: // of the console logger. // -------------------------------------------------------------------------------------- -class ConsoleTestThread : public Threading::PersistentThread +class ConsoleTestThread : public Threading::pxThread { - typedef PersistentThread _parent; + typedef pxThread _parent; protected: volatile bool m_done; diff --git a/pcsx2/gui/Dialogs/ModalPopups.h b/pcsx2/gui/Dialogs/ModalPopups.h index b5fca843d0..2d6074a540 100644 --- a/pcsx2/gui/Dialogs/ModalPopups.h +++ b/pcsx2/gui/Dialogs/ModalPopups.h @@ -153,7 +153,7 @@ namespace Dialogs public EventListener_Thread { public: - StuckThreadDialog( wxWindow* parent, StuckThreadActionType action, Threading::PersistentThread& stuck_thread ); + StuckThreadDialog( wxWindow* parent, StuckThreadActionType action, Threading::pxThread& stuck_thread ); virtual ~StuckThreadDialog() throw() {} protected: diff --git a/pcsx2/gui/Dialogs/StuckThreadDialog.cpp b/pcsx2/gui/Dialogs/StuckThreadDialog.cpp index 74699ce59f..8244d5b359 100644 --- a/pcsx2/gui/Dialogs/StuckThreadDialog.cpp +++ b/pcsx2/gui/Dialogs/StuckThreadDialog.cpp @@ -24,7 +24,7 @@ using namespace Threading; // though I would like to have something in place in the distant future. --air -Dialogs::StuckThreadDialog::StuckThreadDialog( wxWindow* parent, StuckThreadActionType action, PersistentThread& stuck_thread ) +Dialogs::StuckThreadDialog::StuckThreadDialog( wxWindow* parent, StuckThreadActionType action, pxThread& stuck_thread ) : wxDialogWithHelpers( parent, _("PCSX2 Thread is not responding") ) { stuck_thread.AddListener( this ); diff --git a/pcsx2/gui/ExecutorThread.cpp b/pcsx2/gui/ExecutorThread.cpp index 101bb478fd..76cf6c9edb 100644 --- a/pcsx2/gui/ExecutorThread.cpp +++ b/pcsx2/gui/ExecutorThread.cpp @@ -357,10 +357,10 @@ private: typedef wxDialogWithHelpers _parent; protected: - PersistentThread* m_thread; + pxThread* m_thread; public: - WaitingForThreadedTaskDialog( PersistentThread* thr, wxWindow* parent, const wxString& title, const wxString& content ); + WaitingForThreadedTaskDialog( pxThread* thr, wxWindow* parent, const wxString& title, const wxString& content ); virtual ~WaitingForThreadedTaskDialog() throw() {} protected: @@ -371,7 +371,7 @@ protected: // -------------------------------------------------------------------------------------- // WaitingForThreadedTaskDialog Implementations // -------------------------------------------------------------------------------------- -WaitingForThreadedTaskDialog::WaitingForThreadedTaskDialog( PersistentThread* thr, wxWindow* parent, const wxString& title, const wxString& content ) +WaitingForThreadedTaskDialog::WaitingForThreadedTaskDialog( pxThread* thr, wxWindow* parent, const wxString& title, const wxString& content ) : wxDialogWithHelpers( parent, title ) { SetMinWidth( 500 ); diff --git a/pcsx2/gui/MessageBoxes.cpp b/pcsx2/gui/MessageBoxes.cpp index b6d9d11de6..ecfb369f2a 100644 --- a/pcsx2/gui/MessageBoxes.cpp +++ b/pcsx2/gui/MessageBoxes.cpp @@ -44,7 +44,7 @@ static int pxMessageDialog( const wxString& caption, const wxString& content, co // -------------------------------------------------------------------------------------- // BaseMessageBoxEvent Implementation // -------------------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS( BaseMessageBoxEvent, pxInvokeActionEvent ) +IMPLEMENT_DYNAMIC_CLASS( BaseMessageBoxEvent, pxActionEvent ) BaseMessageBoxEvent::BaseMessageBoxEvent( const wxString& content, SynchronousActionState& instdata ) : m_Content( content ) diff --git a/pcsx2/gui/Panels/ConfigurationPanels.h b/pcsx2/gui/Panels/ConfigurationPanels.h index a569e38e96..96cf0530a5 100644 --- a/pcsx2/gui/Panels/ConfigurationPanels.h +++ b/pcsx2/gui/Panels/ConfigurationPanels.h @@ -465,7 +465,7 @@ namespace Panels }; // ---------------------------------------------------------------------------- - class EnumThread : public Threading::PersistentThread + class EnumThread : public Threading::pxThread { public: SafeList Results; // array of plugin results. @@ -476,7 +476,7 @@ namespace Panels public: virtual ~EnumThread() throw() { - PersistentThread::Cancel(); + pxThread::Cancel(); } EnumThread( PluginSelectorPanel& master ); diff --git a/pcsx2/gui/Panels/PluginSelectorPanel.cpp b/pcsx2/gui/Panels/PluginSelectorPanel.cpp index e47e33b384..d5e6d1bd8c 100644 --- a/pcsx2/gui/Panels/PluginSelectorPanel.cpp +++ b/pcsx2/gui/Panels/PluginSelectorPanel.cpp @@ -161,10 +161,10 @@ public: // -------------------------------------------------------------------------------------- // ApplyOverValidStateEvent // -------------------------------------------------------------------------------------- -class ApplyOverValidStateEvent : public pxInvokeActionEvent +class ApplyOverValidStateEvent : public pxActionEvent { //DeclareNoncopyableObject( ApplyOverValidStateEvent ); - typedef pxInvokeActionEvent _parent; + typedef pxActionEvent _parent; protected: ApplyPluginsDialog* m_owner; @@ -744,7 +744,7 @@ void Panels::PluginSelectorPanel::OnProgress( wxCommandEvent& evt ) // -------------------------------------------------------------------------------------- Panels::PluginSelectorPanel::EnumThread::EnumThread( PluginSelectorPanel& master ) - : PersistentThread() + : pxThread() , Results( master.FileCount(), L"PluginSelectorResults" ) , m_master( master ) , m_hourglass( Cursor_KindaBusy ) diff --git a/pcsx2/gui/UpdateUI.cpp b/pcsx2/gui/UpdateUI.cpp index 1a15f7373a..ebc9160399 100644 --- a/pcsx2/gui/UpdateUI.cpp +++ b/pcsx2/gui/UpdateUI.cpp @@ -42,7 +42,7 @@ static void _SaveLoadStuff( bool enabled ) // etc. Typically called by SysEvtHandler whenever the message pump becomes idle. void UI_UpdateSysControls() { - if( wxGetApp().PostMethodMyself( &UI_UpdateSysControls ) ) return; + if( wxGetApp().Rpc_TryInvokeAsync( &UI_UpdateSysControls ) ) return; sApp.PostAction( CoreThreadStatusEvent( CoreThread_Indeterminate ) ); @@ -51,7 +51,7 @@ void UI_UpdateSysControls() void UI_DisableSysReset() { - if( wxGetApp().PostMethodMyself( UI_DisableSysReset ) ) return; + if( wxGetApp().Rpc_TryInvokeAsync( UI_DisableSysReset ) ) return; sMainFrame.EnableMenuItem( MenuId_Sys_Restart, false ); _SaveLoadStuff( false ); @@ -59,7 +59,7 @@ void UI_DisableSysReset() void UI_DisableSysShutdown() { - if( wxGetApp().PostMethodMyself( &UI_DisableSysShutdown ) ) return; + if( wxGetApp().Rpc_TryInvokeAsync( &UI_DisableSysShutdown ) ) return; sMainFrame.EnableMenuItem( MenuId_Sys_Restart, false ); sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, false ); @@ -67,7 +67,7 @@ void UI_DisableSysShutdown() void UI_EnableSysShutdown() { - if( wxGetApp().PostMethodMyself( &UI_EnableSysShutdown ) ) return; + if( wxGetApp().Rpc_TryInvokeAsync( &UI_EnableSysShutdown ) ) return; sMainFrame.EnableMenuItem( MenuId_Sys_Restart, true ); sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, true ); @@ -76,7 +76,7 @@ void UI_EnableSysShutdown() void UI_DisableSysActions() { - if( wxGetApp().PostMethodMyself( &UI_DisableSysActions ) ) return; + if( wxGetApp().Rpc_TryInvokeAsync( &UI_DisableSysActions ) ) return; sMainFrame.EnableMenuItem( MenuId_Sys_Restart, false ); sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, false ); @@ -86,7 +86,7 @@ void UI_DisableSysActions() void UI_EnableSysActions() { - if( wxGetApp().PostMethodMyself( &UI_EnableSysActions ) ) return; + if( wxGetApp().Rpc_TryInvokeAsync( &UI_EnableSysActions ) ) return; sMainFrame.EnableMenuItem( MenuId_Sys_Restart, true ); sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, true ); @@ -96,13 +96,13 @@ void UI_EnableSysActions() void UI_DisableStateActions() { - if( wxGetApp().PostMethodMyself( &UI_DisableStateActions ) ) return; + if( wxGetApp().Rpc_TryInvokeAsync( &UI_DisableStateActions ) ) return; _SaveLoadStuff( false ); } void UI_EnableStateActions() { - if( wxGetApp().PostMethodMyself( &UI_EnableStateActions ) ) return; + if( wxGetApp().Rpc_TryInvokeAsync( &UI_EnableStateActions ) ) return; _SaveLoadStuff( true ); } diff --git a/pcsx2/gui/pxEventThread.h b/pcsx2/gui/pxEventThread.h index 5aa2b5a9e1..52b3998728 100644 --- a/pcsx2/gui/pxEventThread.h +++ b/pcsx2/gui/pxEventThread.h @@ -204,9 +204,9 @@ protected: // Threaded wrapper class for implementing pxEvtHandler. Simply create the desired // EvtHandler, start the thread, and enjoy queued event execution in fully blocking fashion. // -class ExecutorThread : public Threading::PersistentThread +class ExecutorThread : public Threading::pxThread { - typedef Threading::PersistentThread _parent; + typedef Threading::pxThread _parent; protected: ScopedPtr m_ExecutorTimer; diff --git a/pcsx2/windows/WinConsolePipe.cpp b/pcsx2/windows/WinConsolePipe.cpp index da7be63993..0d67e75bd7 100644 --- a/pcsx2/windows/WinConsolePipe.cpp +++ b/pcsx2/windows/WinConsolePipe.cpp @@ -58,9 +58,9 @@ using namespace Threading; // -------------------------------------------------------------------------------------- // WinPipeThread // -------------------------------------------------------------------------------------- -class WinPipeThread : public PersistentThread +class WinPipeThread : public pxThread { - typedef PersistentThread _parent; + typedef pxThread _parent; protected: const HANDLE& m_outpipe;