mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-23 03:30:10 +00:00
Fix EmuThread loop by ensuring it exits properly.
Note: There is a pre-existing issue with booting a new game in that it keeps the old EmuThread. The GL code now supports this but the Core still doesn't.
This commit is contained in:
parent
a3a70e56ac
commit
b044510fa9
@ -20,7 +20,8 @@
|
|||||||
|
|
||||||
EmuThread::EmuThread(GRenderWindow* render_window) :
|
EmuThread::EmuThread(GRenderWindow* render_window) :
|
||||||
exec_cpu_step(false), cpu_running(false),
|
exec_cpu_step(false), cpu_running(false),
|
||||||
render_window(render_window), filename("")
|
render_window(render_window), filename(""),
|
||||||
|
stop_run(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,6 +32,7 @@ void EmuThread::SetFilename(std::string filename)
|
|||||||
|
|
||||||
void EmuThread::run()
|
void EmuThread::run()
|
||||||
{
|
{
|
||||||
|
stop_run = false;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
for (int tight_loop = 0; tight_loop < 10000; ++tight_loop)
|
for (int tight_loop = 0; tight_loop < 10000; ++tight_loop)
|
||||||
@ -41,11 +43,17 @@ void EmuThread::run()
|
|||||||
exec_cpu_step = false;
|
exec_cpu_step = false;
|
||||||
|
|
||||||
Core::SingleStep();
|
Core::SingleStep();
|
||||||
if (!cpu_running)
|
if (!cpu_running) {
|
||||||
emit CPUStepped();
|
emit CPUStepped();
|
||||||
|
yieldCurrentThread();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
QMutexLocker lock(&mutex);
|
||||||
|
if (stop_run)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
render_window->moveContext();
|
||||||
|
|
||||||
Core::Stop();
|
Core::Stop();
|
||||||
}
|
}
|
||||||
@ -58,16 +66,24 @@ void EmuThread::Stop()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
QMutexLocker lock(&mutex);
|
||||||
|
stop_run = true;
|
||||||
|
}
|
||||||
|
|
||||||
//core::g_state = core::SYS_DIE;
|
//core::g_state = core::SYS_DIE;
|
||||||
|
|
||||||
wait(1000);
|
wait(500);
|
||||||
if (isRunning())
|
if (isRunning())
|
||||||
{
|
{
|
||||||
WARN_LOG(MASTER_LOG, "EmuThread still running, terminating...");
|
WARN_LOG(MASTER_LOG, "EmuThread still running, terminating...");
|
||||||
terminate();
|
quit();
|
||||||
wait(1000);
|
wait(1000);
|
||||||
if (isRunning())
|
if (isRunning())
|
||||||
|
{
|
||||||
WARN_LOG(MASTER_LOG, "EmuThread STILL running, something is wrong here...");
|
WARN_LOG(MASTER_LOG, "EmuThread STILL running, something is wrong here...");
|
||||||
|
terminate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
INFO_LOG(MASTER_LOG, "EmuThread stopped");
|
INFO_LOG(MASTER_LOG, "EmuThread stopped");
|
||||||
}
|
}
|
||||||
@ -116,7 +132,6 @@ GRenderWindow::GRenderWindow(QWidget* parent) : QWidget(parent), emu_thread(this
|
|||||||
layout->setMargin(0);
|
layout->setMargin(0);
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
QObject::connect(&emu_thread, SIGNAL(started()), this, SLOT(moveContext()));
|
QObject::connect(&emu_thread, SIGNAL(started()), this, SLOT(moveContext()));
|
||||||
QObject::connect(&emu_thread, SIGNAL(finished()), this, SLOT(moveContext()));
|
|
||||||
|
|
||||||
BackupGeometry();
|
BackupGeometry();
|
||||||
}
|
}
|
||||||
@ -127,12 +142,13 @@ void GRenderWindow::moveContext()
|
|||||||
// We need to move GL context to the swapping thread in Qt5
|
// We need to move GL context to the swapping thread in Qt5
|
||||||
#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
|
#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
|
||||||
// If the thread started running, move the GL Context to the new thread. Otherwise, move it back.
|
// If the thread started running, move the GL Context to the new thread. Otherwise, move it back.
|
||||||
child->context()->moveToThread(emu_thread.isRunning() ? &emu_thread : qApp->thread());
|
child->context()->moveToThread((QThread::currentThread() == qApp->thread()) ? &emu_thread : qApp->thread());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
GRenderWindow::~GRenderWindow()
|
GRenderWindow::~GRenderWindow()
|
||||||
{
|
{
|
||||||
|
if (emu_thread.isRunning())
|
||||||
emu_thread.Stop();
|
emu_thread.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,6 +160,7 @@ void GRenderWindow::SwapBuffers()
|
|||||||
|
|
||||||
void GRenderWindow::closeEvent(QCloseEvent* event)
|
void GRenderWindow::closeEvent(QCloseEvent* event)
|
||||||
{
|
{
|
||||||
|
if (emu_thread.isRunning())
|
||||||
emu_thread.Stop();
|
emu_thread.Stop();
|
||||||
QWidget::closeEvent(event);
|
QWidget::closeEvent(event);
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include <QMutex>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QGLWidget>
|
#include <QGLWidget>
|
||||||
#include "common/common.h"
|
#include "common/common.h"
|
||||||
@ -66,6 +67,8 @@ private:
|
|||||||
|
|
||||||
bool exec_cpu_step;
|
bool exec_cpu_step;
|
||||||
bool cpu_running;
|
bool cpu_running;
|
||||||
|
bool stop_run;
|
||||||
|
QMutex mutex;
|
||||||
|
|
||||||
GRenderWindow* render_window;
|
GRenderWindow* render_window;
|
||||||
|
|
||||||
@ -105,7 +108,7 @@ public:
|
|||||||
void keyPressEvent(QKeyEvent* event);
|
void keyPressEvent(QKeyEvent* event);
|
||||||
void keyReleaseEvent(QKeyEvent* event);
|
void keyReleaseEvent(QKeyEvent* event);
|
||||||
|
|
||||||
private slots:
|
public slots:
|
||||||
void moveContext();
|
void moveContext();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Loading…
Reference in New Issue
Block a user