Changed QMutex to be recursive to prevent dead-locks in gui and emulator. A few bug fixes for the palette config window.

This commit is contained in:
Matthew Budd 2020-07-17 21:50:23 -04:00
parent be7dcda45e
commit 6fb247d785
6 changed files with 114 additions and 53 deletions

View File

@ -262,10 +262,12 @@ void ConsoleSndConfDialog_t::bufSizeChanged(int value)
g_config->setOption ("SDL.Sound.BufSize", value); g_config->setOption ("SDL.Sound.BufSize", value);
// reset sound subsystem for changes to take effect // reset sound subsystem for changes to take effect
fceuWrapperLock(); if ( fceuWrapperTryLock() )
KillSound (); {
InitSound (); KillSound ();
fceuWrapperUnLock(); InitSound ();
fceuWrapperUnLock();
}
} }
//---------------------------------------------------- //----------------------------------------------------
void ConsoleSndConfDialog_t::volumeChanged(int value) void ConsoleSndConfDialog_t::volumeChanged(int value)
@ -278,9 +280,11 @@ void ConsoleSndConfDialog_t::volumeChanged(int value)
g_config->setOption ("SDL.Sound.Volume", value); g_config->setOption ("SDL.Sound.Volume", value);
fceuWrapperLock(); if ( fceuWrapperTryLock() )
FCEUI_SetSoundVolume (value); {
fceuWrapperUnLock(); FCEUI_SetSoundVolume (value);
fceuWrapperUnLock();
}
} }
//---------------------------------------------------- //----------------------------------------------------
void ConsoleSndConfDialog_t::triangleChanged(int value) void ConsoleSndConfDialog_t::triangleChanged(int value)
@ -293,9 +297,11 @@ void ConsoleSndConfDialog_t::triangleChanged(int value)
g_config->setOption ("SDL.Sound.TriangleVolume", value); g_config->setOption ("SDL.Sound.TriangleVolume", value);
fceuWrapperLock(); if ( fceuWrapperTryLock() )
FCEUI_SetTriangleVolume (value); {
fceuWrapperUnLock(); FCEUI_SetTriangleVolume (value);
fceuWrapperUnLock();
}
} }
//---------------------------------------------------- //----------------------------------------------------
void ConsoleSndConfDialog_t::square1Changed(int value) void ConsoleSndConfDialog_t::square1Changed(int value)
@ -308,9 +314,11 @@ void ConsoleSndConfDialog_t::square1Changed(int value)
g_config->setOption ("SDL.Sound.Square1Volume", value); g_config->setOption ("SDL.Sound.Square1Volume", value);
fceuWrapperLock(); if ( fceuWrapperTryLock() )
FCEUI_SetSquare1Volume (value); {
fceuWrapperUnLock(); FCEUI_SetSquare1Volume (value);
fceuWrapperUnLock();
}
} }
//---------------------------------------------------- //----------------------------------------------------
void ConsoleSndConfDialog_t::square2Changed(int value) void ConsoleSndConfDialog_t::square2Changed(int value)
@ -323,9 +331,11 @@ void ConsoleSndConfDialog_t::square2Changed(int value)
g_config->setOption ("SDL.Sound.Square2Volume", value); g_config->setOption ("SDL.Sound.Square2Volume", value);
fceuWrapperLock(); if ( fceuWrapperTryLock() )
FCEUI_SetSquare2Volume (value); {
fceuWrapperUnLock(); FCEUI_SetSquare2Volume (value);
fceuWrapperUnLock();
}
} }
//---------------------------------------------------- //----------------------------------------------------
void ConsoleSndConfDialog_t::noiseChanged(int value) void ConsoleSndConfDialog_t::noiseChanged(int value)
@ -338,9 +348,11 @@ void ConsoleSndConfDialog_t::noiseChanged(int value)
g_config->setOption ("SDL.Sound.NoiseVolume", value); g_config->setOption ("SDL.Sound.NoiseVolume", value);
fceuWrapperLock(); if ( fceuWrapperTryLock() )
FCEUI_SetNoiseVolume (value); {
fceuWrapperUnLock(); FCEUI_SetNoiseVolume (value);
fceuWrapperUnLock();
}
} }
//---------------------------------------------------- //----------------------------------------------------
void ConsoleSndConfDialog_t::pcmChanged(int value) void ConsoleSndConfDialog_t::pcmChanged(int value)
@ -353,9 +365,11 @@ void ConsoleSndConfDialog_t::pcmChanged(int value)
g_config->setOption ("SDL.Sound.PCMVolume", value); g_config->setOption ("SDL.Sound.PCMVolume", value);
fceuWrapperLock(); if ( fceuWrapperTryLock() )
FCEUI_SetPCMVolume (value); {
fceuWrapperUnLock(); FCEUI_SetPCMVolume (value);
fceuWrapperUnLock();
}
} }
//---------------------------------------------------- //----------------------------------------------------
void ConsoleSndConfDialog_t::enaSoundStateChange(int value) void ConsoleSndConfDialog_t::enaSoundStateChange(int value)
@ -427,10 +441,12 @@ void ConsoleSndConfDialog_t::soundQualityChanged(int index)
g_config->setOption ("SDL.Sound.Quality", qualitySelect->itemData(index).toInt() ); g_config->setOption ("SDL.Sound.Quality", qualitySelect->itemData(index).toInt() );
// reset sound subsystem for changes to take effect // reset sound subsystem for changes to take effect
fceuWrapperLock(); if ( fceuWrapperTryLock() )
KillSound (); {
InitSound (); KillSound ();
fceuWrapperUnLock(); InitSound ();
fceuWrapperUnLock();
}
g_config->save (); g_config->save ();
} }
//---------------------------------------------------- //----------------------------------------------------
@ -440,10 +456,12 @@ void ConsoleSndConfDialog_t::soundRateChanged(int index)
g_config->setOption ("SDL.Sound.Rate", rateSelect->itemData(index).toInt() ); g_config->setOption ("SDL.Sound.Rate", rateSelect->itemData(index).toInt() );
// reset sound subsystem for changes to take effect // reset sound subsystem for changes to take effect
fceuWrapperLock(); if ( fceuWrapperTryLock() )
KillSound (); {
InitSound (); KillSound ();
fceuWrapperUnLock(); InitSound ();
fceuWrapperUnLock();
}
g_config->save (); g_config->save ();
} }
//---------------------------------------------------- //----------------------------------------------------

View File

@ -40,7 +40,7 @@ consoleWin_t::consoleWin_t(QWidget *parent)
setWindowIcon(QIcon(":fceux1.png")); setWindowIcon(QIcon(":fceux1.png"));
gameTimer = new QTimer( this ); gameTimer = new QTimer( this );
mutex = new QMutex( QMutex::NonRecursive ); mutex = new QMutex( QMutex::Recursive );
emulatorThread = new emulatorThread_t(); emulatorThread = new emulatorThread_t();
connect(emulatorThread, &QThread::finished, emulatorThread, &QObject::deleteLater); connect(emulatorThread, &QThread::finished, emulatorThread, &QObject::deleteLater);

View File

@ -16,10 +16,11 @@ PaletteConfDialog_t::PaletteConfDialog_t(QWidget *parent)
QVBoxLayout *mainLayout, *vbox; QVBoxLayout *mainLayout, *vbox;
QHBoxLayout *hbox1; QHBoxLayout *hbox1;
QGroupBox *frame; QGroupBox *frame;
QPushButton *closebutton; //QPushButton *closebutton;
QPushButton *button; QPushButton *button;
int hue, tint; int hue, tint;
char stmp[64]; char stmp[64];
std::string paletteFile;
// sync with config // sync with config
g_config->getOption ("SDL.Hue", &hue); g_config->getOption ("SDL.Hue", &hue);
@ -37,8 +38,11 @@ PaletteConfDialog_t::PaletteConfDialog_t(QWidget *parent)
connect( button, SIGNAL(clicked(void)), this, SLOT(openPaletteFile(void)) ); connect( button, SIGNAL(clicked(void)), this, SLOT(openPaletteFile(void)) );
g_config->getOption ("SDL.Palette", &paletteFile);
custom_palette_path = new QLineEdit(); custom_palette_path = new QLineEdit();
custom_palette_path->setReadOnly(true); custom_palette_path->setReadOnly(true);
custom_palette_path->setText( paletteFile.c_str() );
hbox1->addWidget( custom_palette_path ); hbox1->addWidget( custom_palette_path );
button = new QPushButton( tr("Clear") ); button = new QPushButton( tr("Clear") );
@ -124,9 +128,11 @@ void PaletteConfDialog_t::hueChanged(int v)
g_config->getOption ("SDL.Tint", &t); g_config->getOption ("SDL.Tint", &t);
g_config->getOption ("SDL.NTSCpalette", &c); g_config->getOption ("SDL.NTSCpalette", &c);
fceuWrapperLock(); if ( fceuWrapperTryLock() )
FCEUI_SetNTSCTH (c, t, v); {
fceuWrapperUnLock(); FCEUI_SetNTSCTH (c, t, v);
fceuWrapperUnLock();
}
} }
//---------------------------------------------------- //----------------------------------------------------
void PaletteConfDialog_t::tintChanged(int v) void PaletteConfDialog_t::tintChanged(int v)
@ -143,24 +149,42 @@ void PaletteConfDialog_t::tintChanged(int v)
g_config->getOption ("SDL.NTSCpalette", &c); g_config->getOption ("SDL.NTSCpalette", &c);
g_config->getOption ("SDL.Hue", &h); g_config->getOption ("SDL.Hue", &h);
fceuWrapperLock(); if ( fceuWrapperTryLock() )
FCEUI_SetNTSCTH (c, v, h); {
fceuWrapperUnLock(); FCEUI_SetNTSCTH (c, v, h);
fceuWrapperUnLock();
}
} }
//---------------------------------------------------- //----------------------------------------------------
void PaletteConfDialog_t::use_NTSC_Changed(int state) void PaletteConfDialog_t::use_NTSC_Changed(int state)
{ {
int h, t;
int value = (state == Qt::Unchecked) ? 0 : 1; int value = (state == Qt::Unchecked) ? 0 : 1;
g_config->setOption ("SDL.NTSCpalette", value); g_config->setOption ("SDL.NTSCpalette", value);
g_config->save (); g_config->save ();
UpdateEMUCore (g_config);
g_config->getOption ("SDL.Hue", &h);
g_config->getOption ("SDL.Tint", &t);
if ( fceuWrapperTryLock() )
{
FCEUI_SetNTSCTH (value, t, h);
//UpdateEMUCore (g_config);
fceuWrapperUnLock();
}
} }
//---------------------------------------------------- //----------------------------------------------------
void PaletteConfDialog_t::clearPalette(void) void PaletteConfDialog_t::clearPalette(void)
{ {
g_config->setOption ("SDL.Palette", 0); g_config->setOption ("SDL.Palette", "");
custom_palette_path->setText(""); custom_palette_path->setText("");
if ( fceuWrapperTryLock() )
{
FCEUI_SetUserPalette( NULL, 0);
fceuWrapperUnLock();
}
} }
//---------------------------------------------------- //----------------------------------------------------
void PaletteConfDialog_t::openPaletteFile(void) void PaletteConfDialog_t::openPaletteFile(void)
@ -204,9 +228,11 @@ void PaletteConfDialog_t::openPaletteFile(void)
g_config->setOption ("SDL.Palette", filename.toStdString().c_str() ); g_config->setOption ("SDL.Palette", filename.toStdString().c_str() );
g_config->setOption ("SDL.NTSCpalette", 0); g_config->setOption ("SDL.NTSCpalette", 0);
fceuWrapperLock(); if ( fceuWrapperTryLock() )
LoadCPalette ( filename.toStdString().c_str() ); {
fceuWrapperUnLock(); LoadCPalette ( filename.toStdString().c_str() );
fceuWrapperUnLock();
}
custom_palette_path->setText( filename.toStdString().c_str() ); custom_palette_path->setText( filename.toStdString().c_str() );

View File

@ -56,7 +56,8 @@ static int inited = 0;
static int noconfig=0; static int noconfig=0;
static int frameskip=0; static int frameskip=0;
static int periodic_saves = 0; static int periodic_saves = 0;
static bool mutexLocked = 0; static int mutexLocks = 0;
static bool emulatorHasMutux = 0;
extern double g_fpsScale; extern double g_fpsScale;
@ -78,6 +79,7 @@ int mutecapture = 0;
void FCEUD_Message(const char *text) void FCEUD_Message(const char *text)
{ {
fputs(text, stdout); fputs(text, stdout);
fprintf(stdout, "\n");
} }
/** /**
@ -911,7 +913,7 @@ static void DoFun(int frameskip, int periodic_saves)
void fceuWrapperLock(void) void fceuWrapperLock(void)
{ {
consoleWindow->mutex->lock(); consoleWindow->mutex->lock();
mutexLocked = 1; mutexLocks++;
} }
bool fceuWrapperTryLock(int timeout) bool fceuWrapperTryLock(int timeout)
@ -922,17 +924,17 @@ bool fceuWrapperTryLock(int timeout)
if ( lockAcq ) if ( lockAcq )
{ {
mutexLocked = 1; mutexLocks++;
} }
return lockAcq; return lockAcq;
} }
void fceuWrapperUnLock(void) void fceuWrapperUnLock(void)
{ {
if ( mutexLocked ) if ( mutexLocks > 0 )
{ {
consoleWindow->mutex->unlock(); consoleWindow->mutex->unlock();
mutexLocked = 0; mutexLocks--;
} }
else else
{ {
@ -942,12 +944,23 @@ void fceuWrapperUnLock(void)
bool fceuWrapperIsLocked(void) bool fceuWrapperIsLocked(void)
{ {
return mutexLocked; return mutexLocks > 0;
} }
int fceuWrapperUpdate( void ) int fceuWrapperUpdate( void )
{ {
fceuWrapperLock(); bool lock_acq;
lock_acq = fceuWrapperTryLock();
if ( !lock_acq )
{
printf("Error: Emulator Failed to Acquire Mutex\n");
usleep( 100000 );
return -1;
}
emulatorHasMutux = 1;
if ( GameInfo && !FCEUI_EmulationPaused() ) if ( GameInfo && !FCEUI_EmulationPaused() )
{ {
@ -955,6 +968,8 @@ int fceuWrapperUpdate( void )
fceuWrapperUnLock(); fceuWrapperUnLock();
emulatorHasMutux = 0;
while ( SpeedThrottle() ) while ( SpeedThrottle() )
{ {
// Input device processing is in main thread // Input device processing is in main thread
@ -966,6 +981,8 @@ int fceuWrapperUpdate( void )
{ {
fceuWrapperUnLock(); fceuWrapperUnLock();
emulatorHasMutux = 0;
usleep( 100000 ); usleep( 100000 );
} }
return 0; return 0;

View File

@ -26,7 +26,7 @@ int fceuWrapperInit( int argc, char *argv[] );
int fceuWrapperClose( void ); int fceuWrapperClose( void );
int fceuWrapperUpdate( void ); int fceuWrapperUpdate( void );
void fceuWrapperLock(void); void fceuWrapperLock(void);
bool fceuWrapperTryLock(int timeout); bool fceuWrapperTryLock(int timeout = 1000);
bool fceuWrapperIsLocked(void); bool fceuWrapperIsLocked(void);
void fceuWrapperUnLock(void); void fceuWrapperUnLock(void);
int fceuWrapperSoftReset(void); int fceuWrapperSoftReset(void);

View File

@ -46,8 +46,8 @@ pal palette_game[64*8]; //custom palette for an individual game. (formerly palet
pal palette_user[64*8]; //user's overridden palette (formerly palettec) pal palette_user[64*8]; //user's overridden palette (formerly palettec)
pal palette_ntsc[64*8]; //mathematically generated NTSC palette (formerly paletten) pal palette_ntsc[64*8]; //mathematically generated NTSC palette (formerly paletten)
static bool palette_game_available; //whether palette_game is available static bool palette_game_available=false; //whether palette_game is available
static bool palette_user_available; //whether palette_user is available static bool palette_user_available=false; //whether palette_user is available
//ntsc parameters: //ntsc parameters:
bool ntsccol_enable = false; //whether NTSC palette is selected bool ntsccol_enable = false; //whether NTSC palette is selected