mirror of https://github.com/PCSX2/pcsx2.git
wxgui: improve single-threaded plugin enumerator for Linux (still a bit buggy)
git-svn-id: http://pcsx2.googlecode.com/svn/branches/wxgui@1743 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
0fa673fdd2
commit
93e1d87a22
|
@ -50,6 +50,8 @@ namespace Threading
|
||||||
// your sister, and then cheating on her with your daughter.
|
// your sister, and then cheating on her with your daughter.
|
||||||
PersistentThread::~PersistentThread()
|
PersistentThread::~PersistentThread()
|
||||||
{
|
{
|
||||||
|
if( !m_running ) return;
|
||||||
|
|
||||||
wxASSERT( !IsSelf() ); // not allowed from our own thread.
|
wxASSERT( !IsSelf() ); // not allowed from our own thread.
|
||||||
|
|
||||||
if( !_InterlockedExchange( &m_detached, true ) )
|
if( !_InterlockedExchange( &m_detached, true ) )
|
||||||
|
@ -62,9 +64,7 @@ namespace Threading
|
||||||
// This function should not be called from the owner thread.
|
// This function should not be called from the owner thread.
|
||||||
void PersistentThread::Start()
|
void PersistentThread::Start()
|
||||||
{
|
{
|
||||||
wxASSERT( !IsSelf() ); // not allowed from our own thread.
|
|
||||||
if( m_running ) return;
|
if( m_running ) return;
|
||||||
|
|
||||||
if( pthread_create( &m_thread, NULL, _internal_callback, this ) != 0 )
|
if( pthread_create( &m_thread, NULL, _internal_callback, this ) != 0 )
|
||||||
throw Exception::ThreadCreationError();
|
throw Exception::ThreadCreationError();
|
||||||
|
|
||||||
|
@ -74,8 +74,10 @@ namespace Threading
|
||||||
// This function should not be called from the owner thread.
|
// This function should not be called from the owner thread.
|
||||||
void PersistentThread::Detach()
|
void PersistentThread::Detach()
|
||||||
{
|
{
|
||||||
wxASSERT( !IsSelf() ); // not allowed from our own thread.
|
if( !m_running ) return;
|
||||||
if( _InterlockedExchange( &m_detached, true ) ) return;
|
if( _InterlockedExchange( &m_detached, true ) ) return;
|
||||||
|
|
||||||
|
wxASSERT( !IsSelf() ); // not allowed from our own thread.
|
||||||
pthread_detach( m_thread );
|
pthread_detach( m_thread );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +94,6 @@ namespace Threading
|
||||||
//
|
//
|
||||||
void PersistentThread::Cancel( bool isBlocking )
|
void PersistentThread::Cancel( bool isBlocking )
|
||||||
{
|
{
|
||||||
wxASSERT( !IsSelf() );
|
|
||||||
if( _InterlockedExchange( &m_detached, true ) )
|
if( _InterlockedExchange( &m_detached, true ) )
|
||||||
{
|
{
|
||||||
if( m_running )
|
if( m_running )
|
||||||
|
@ -100,6 +101,7 @@ namespace Threading
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxASSERT( !IsSelf() );
|
||||||
pthread_cancel( m_thread );
|
pthread_cancel( m_thread );
|
||||||
|
|
||||||
if( isBlocking )
|
if( isBlocking )
|
||||||
|
@ -120,8 +122,6 @@ namespace Threading
|
||||||
//
|
//
|
||||||
sptr PersistentThread::Block()
|
sptr PersistentThread::Block()
|
||||||
{
|
{
|
||||||
DevAssert( !IsSelf(), "Thread deadlock detected; Block() should never be called by the owner thread." );
|
|
||||||
|
|
||||||
if( _InterlockedExchange( &m_detached, true ) )
|
if( _InterlockedExchange( &m_detached, true ) )
|
||||||
{
|
{
|
||||||
// already detached: if we're still running then its an invalid operation
|
// already detached: if we're still running then its an invalid operation
|
||||||
|
@ -132,6 +132,7 @@ namespace Threading
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
DevAssert( !IsSelf(), "Thread deadlock detected; Block() should never be called by the owner thread." );
|
||||||
pthread_join( m_thread, (void**)&m_returncode );
|
pthread_join( m_thread, (void**)&m_returncode );
|
||||||
return m_returncode;
|
return m_returncode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,8 +134,6 @@
|
||||||
<Unit filename="../CDVD/IsoFileFormats.h" />
|
<Unit filename="../CDVD/IsoFileFormats.h" />
|
||||||
<Unit filename="../CDVD/IsoFileTools.cpp" />
|
<Unit filename="../CDVD/IsoFileTools.cpp" />
|
||||||
<Unit filename="../CDVD/IsoFileTools.h" />
|
<Unit filename="../CDVD/IsoFileTools.h" />
|
||||||
<Unit filename="../CDVD/IsoFileTools.h.save" />
|
|
||||||
<Unit filename="../CDVD/Makefile.am" />
|
|
||||||
<Unit filename="../COP0.cpp" />
|
<Unit filename="../COP0.cpp" />
|
||||||
<Unit filename="../COP2.cpp" />
|
<Unit filename="../COP2.cpp" />
|
||||||
<Unit filename="../Cache.cpp" />
|
<Unit filename="../Cache.cpp" />
|
||||||
|
@ -155,11 +153,7 @@
|
||||||
<Unit filename="../DebugTools/DisVUops.h" />
|
<Unit filename="../DebugTools/DisVUops.h" />
|
||||||
<Unit filename="../Docs/ChangeLog.txt" />
|
<Unit filename="../Docs/ChangeLog.txt" />
|
||||||
<Unit filename="../Docs/License.txt" />
|
<Unit filename="../Docs/License.txt" />
|
||||||
<Unit filename="../Docs/PS2Edefs.txt" />
|
|
||||||
<Unit filename="../Docs/RemoteDebugging.txt" />
|
|
||||||
<Unit filename="../Docs/devblog.txt" />
|
<Unit filename="../Docs/devblog.txt" />
|
||||||
<Unit filename="../Docs/readme 0.9.4.txt" />
|
|
||||||
<Unit filename="../Docs/readme Playground.txt" />
|
|
||||||
<Unit filename="../Dump.cpp" />
|
<Unit filename="../Dump.cpp" />
|
||||||
<Unit filename="../Dump.h" />
|
<Unit filename="../Dump.h" />
|
||||||
<Unit filename="../Elfheader.cpp" />
|
<Unit filename="../Elfheader.cpp" />
|
||||||
|
|
|
@ -22,12 +22,12 @@
|
||||||
#include <wx/stdpaths.h>
|
#include <wx/stdpaths.h>
|
||||||
|
|
||||||
using namespace wxHelpers;
|
using namespace wxHelpers;
|
||||||
|
using namespace Panels;
|
||||||
|
|
||||||
Dialogs::PickUserModeDialog::PickUserModeDialog( wxWindow* parent, int id ) :
|
Dialogs::PickUserModeDialog::PickUserModeDialog( wxWindow* parent, int id ) :
|
||||||
wxDialogWithHelpers( parent, id, _("PCSX2 First Time configuration"), false )
|
wxDialogWithHelpers( parent, id, _("PCSX2 First Time configuration"), false )
|
||||||
, m_panel_usersel( new Panels::UsermodeSelectionPanel( *this, 620, false ) )
|
, m_panel_usersel( new UsermodeSelectionPanel( *this, 620, false ) )
|
||||||
, m_panel_langsel( new Panels::LanguageSelectionPanel( *this, 620 ) )
|
, m_panel_langsel( new LanguageSelectionPanel( *this, 620 ) )
|
||||||
{
|
{
|
||||||
wxBoxSizer& s_main = *new wxBoxSizer( wxVERTICAL );
|
wxBoxSizer& s_main = *new wxBoxSizer( wxVERTICAL );
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ Dialogs::PickUserModeDialog::PickUserModeDialog( wxWindow* parent, int id ) :
|
||||||
|
|
||||||
void Dialogs::PickUserModeDialog::OnOk_Click( wxCommandEvent& evt )
|
void Dialogs::PickUserModeDialog::OnOk_Click( wxCommandEvent& evt )
|
||||||
{
|
{
|
||||||
if( Panels::g_ApplyState.ApplyAll(true) )
|
if( g_ApplyState.ApplyAll() )
|
||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
evt.Skip();
|
evt.Skip();
|
||||||
|
|
|
@ -406,6 +406,9 @@ namespace Panels
|
||||||
virtual ~EnumThread();
|
virtual ~EnumThread();
|
||||||
EnumThread( PluginSelectorPanel& master );
|
EnumThread( PluginSelectorPanel& master );
|
||||||
void Cancel();
|
void Cancel();
|
||||||
|
void DoNextPlugin( int evtidx );
|
||||||
|
|
||||||
|
protected:
|
||||||
sptr ExecuteTask();
|
sptr ExecuteTask();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,12 @@
|
||||||
#include <wx/dir.h>
|
#include <wx/dir.h>
|
||||||
|
|
||||||
// Allows us to force-disable threading for debugging/troubleshooting
|
// Allows us to force-disable threading for debugging/troubleshooting
|
||||||
static const bool DisableThreading = true;
|
static const bool DisableThreading =
|
||||||
|
#ifdef __LINUX__
|
||||||
|
true; // linux appears to have threading issues with loadlibrary.
|
||||||
|
#else
|
||||||
|
false;
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace wxHelpers;
|
using namespace wxHelpers;
|
||||||
using namespace Threading;
|
using namespace Threading;
|
||||||
|
@ -287,12 +292,20 @@ void Panels::PluginSelectorPanel::Apply( AppConfig& conf )
|
||||||
|
|
||||||
void Panels::PluginSelectorPanel::CancelRefresh()
|
void Panels::PluginSelectorPanel::CancelRefresh()
|
||||||
{
|
{
|
||||||
if (!DisableThreading) safe_delete( m_EnumeratorThread );
|
safe_delete( m_EnumeratorThread );
|
||||||
safe_delete( m_FileList );
|
safe_delete( m_FileList );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panels::PluginSelectorPanel::DoRefresh()
|
void Panels::PluginSelectorPanel::DoRefresh()
|
||||||
{
|
{
|
||||||
|
m_ComponentBoxes.Reset();
|
||||||
|
if( m_FileList == NULL )
|
||||||
|
{
|
||||||
|
wxCommandEvent evt;
|
||||||
|
OnEnumComplete( evt );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Disable all controls until enumeration is complete.
|
// Disable all controls until enumeration is complete.
|
||||||
// Show status bar for plugin enumeration.
|
// Show status bar for plugin enumeration.
|
||||||
|
|
||||||
|
@ -307,19 +320,13 @@ void Panels::PluginSelectorPanel::DoRefresh()
|
||||||
m_StatusPanel.Show();
|
m_StatusPanel.Show();
|
||||||
|
|
||||||
// Use a thread to load plugins.
|
// Use a thread to load plugins.
|
||||||
if (!DisableThreading) safe_delete( m_EnumeratorThread );
|
safe_delete( m_EnumeratorThread );
|
||||||
m_EnumeratorThread = new EnumThread( *this );
|
m_EnumeratorThread = new EnumThread( *this );
|
||||||
|
|
||||||
if( DisableThreading )
|
if( DisableThreading )
|
||||||
{
|
m_EnumeratorThread->DoNextPlugin( 0 );
|
||||||
m_ComponentBoxes.Reset();
|
|
||||||
m_EnumeratorThread->ExecuteTask();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
m_EnumeratorThread->Start();
|
m_EnumeratorThread->Start();
|
||||||
m_ComponentBoxes.Reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Panels::PluginSelectorPanel::ValidateEnumerationStatus()
|
bool Panels::PluginSelectorPanel::ValidateEnumerationStatus()
|
||||||
|
@ -338,6 +345,12 @@ bool Panels::PluginSelectorPanel::ValidateEnumerationStatus()
|
||||||
if( (m_FileList == NULL) || (*pluginlist != *m_FileList) )
|
if( (m_FileList == NULL) || (*pluginlist != *m_FileList) )
|
||||||
validated = false;
|
validated = false;
|
||||||
|
|
||||||
|
if( pluggers == 0 )
|
||||||
|
{
|
||||||
|
safe_delete( m_FileList );
|
||||||
|
return validated;
|
||||||
|
}
|
||||||
|
|
||||||
delete m_FileList;
|
delete m_FileList;
|
||||||
m_FileList = pluginlist.release();
|
m_FileList = pluginlist.release();
|
||||||
|
|
||||||
|
@ -363,7 +376,7 @@ void Panels::PluginSelectorPanel::OnConfigure_Clicked( wxCommandEvent& evt )
|
||||||
|
|
||||||
void Panels::PluginSelectorPanel::OnEnumComplete( wxCommandEvent& evt )
|
void Panels::PluginSelectorPanel::OnEnumComplete( wxCommandEvent& evt )
|
||||||
{
|
{
|
||||||
if (!DisableThreading) safe_delete( m_EnumeratorThread );
|
safe_delete( m_EnumeratorThread );
|
||||||
|
|
||||||
// fixme: Default plugins should be picked based on the timestamp of the DLL or something?
|
// fixme: Default plugins should be picked based on the timestamp of the DLL or something?
|
||||||
// (for now we just force it to selection zero if nothing's selected)
|
// (for now we just force it to selection zero if nothing's selected)
|
||||||
|
@ -388,7 +401,20 @@ void Panels::PluginSelectorPanel::OnProgress( wxCommandEvent& evt )
|
||||||
{
|
{
|
||||||
if( m_FileList == NULL ) return;
|
if( m_FileList == NULL ) return;
|
||||||
|
|
||||||
size_t evtidx = evt.GetExtraLong();
|
const size_t evtidx = evt.GetExtraLong();
|
||||||
|
|
||||||
|
if( DisableThreading )
|
||||||
|
{
|
||||||
|
const int nextidx = evtidx+1;
|
||||||
|
if( nextidx == m_FileList->Count() )
|
||||||
|
{
|
||||||
|
wxCommandEvent done( wxEVT_EnumerationFinished );
|
||||||
|
GetEventHandler()->AddPendingEvent( done );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_EnumeratorThread->DoNextPlugin( nextidx );
|
||||||
|
}
|
||||||
|
|
||||||
m_StatusPanel.AdvanceProgress( (evtidx < m_FileList->Count()-1) ?
|
m_StatusPanel.AdvanceProgress( (evtidx < m_FileList->Count()-1) ?
|
||||||
(*m_FileList)[evtidx + 1] : wxString(_("Completing tasks..."))
|
(*m_FileList)[evtidx + 1] : wxString(_("Completing tasks..."))
|
||||||
);
|
);
|
||||||
|
@ -449,15 +475,8 @@ void Panels::PluginSelectorPanel::EnumThread::Cancel()
|
||||||
PersistentThread::Cancel();
|
PersistentThread::Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
sptr Panels::PluginSelectorPanel::EnumThread::ExecuteTask()
|
void Panels::PluginSelectorPanel::EnumThread::DoNextPlugin( int curidx )
|
||||||
{
|
{
|
||||||
DevCon::Status( "Plugin Enumeration Thread started..." );
|
|
||||||
|
|
||||||
wxGetApp().Ping(); // gives the gui thread some time to refresh
|
|
||||||
|
|
||||||
for( int curidx=0; curidx < m_master.FileCount(); ++curidx )
|
|
||||||
{
|
|
||||||
if( m_cancel ) return 0;
|
|
||||||
DbgCon::WriteLn( L"Enumerating Plugin: " + m_master.GetFilename( curidx ) );
|
DbgCon::WriteLn( L"Enumerating Plugin: " + m_master.GetFilename( curidx ) );
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -484,11 +503,22 @@ sptr Panels::PluginSelectorPanel::EnumThread::ExecuteTask()
|
||||||
Console::Status( ex.FormatDiagnosticMessage() );
|
Console::Status( ex.FormatDiagnosticMessage() );
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_testcancel();
|
|
||||||
|
|
||||||
wxCommandEvent yay( wxEVT_EnumeratedNext );
|
wxCommandEvent yay( wxEVT_EnumeratedNext );
|
||||||
yay.SetExtraLong( curidx );
|
yay.SetExtraLong( curidx );
|
||||||
m_master.GetEventHandler()->AddPendingEvent( yay );
|
m_master.GetEventHandler()->AddPendingEvent( yay );
|
||||||
|
}
|
||||||
|
|
||||||
|
sptr Panels::PluginSelectorPanel::EnumThread::ExecuteTask()
|
||||||
|
{
|
||||||
|
DevCon::Status( "Plugin Enumeration Thread started..." );
|
||||||
|
|
||||||
|
wxGetApp().Ping(); // gives the gui thread some time to refresh
|
||||||
|
|
||||||
|
for( int curidx=0; curidx < m_master.FileCount(); ++curidx )
|
||||||
|
{
|
||||||
|
if( m_cancel ) return 0;
|
||||||
|
DoNextPlugin( curidx );
|
||||||
|
pthread_testcancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
wxCommandEvent done( wxEVT_EnumerationFinished );
|
wxCommandEvent done( wxEVT_EnumerationFinished );
|
||||||
|
|
Loading…
Reference in New Issue