diff options
| author | 2014-08-25 01:49:34 +1000 | |
|---|---|---|
| committer | 2014-08-25 01:49:34 +1000 | |
| commit | b044510fa946f1eab7e3b5917eba518b9631835a (patch) | |
| tree | 49e6394a403cb4feeedc53df6ed2663b20ca89e3 /src/citra_qt/bootmanager.cpp | |
| parent | Fix the threading for GL Context in Qt5. (diff) | |
| download | yuzu-b044510fa946f1eab7e3b5917eba518b9631835a.tar.gz yuzu-b044510fa946f1eab7e3b5917eba518b9631835a.tar.xz yuzu-b044510fa946f1eab7e3b5917eba518b9631835a.zip | |
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.
Diffstat (limited to 'src/citra_qt/bootmanager.cpp')
| -rw-r--r-- | src/citra_qt/bootmanager.cpp | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index 73f25e691..2407f3a3a 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp | |||
| @@ -20,7 +20,8 @@ | |||
| 20 | 20 | ||
| 21 | EmuThread::EmuThread(GRenderWindow* render_window) : | 21 | EmuThread::EmuThread(GRenderWindow* render_window) : |
| 22 | exec_cpu_step(false), cpu_running(false), | 22 | exec_cpu_step(false), cpu_running(false), |
| 23 | render_window(render_window), filename("") | 23 | render_window(render_window), filename(""), |
| 24 | stop_run(false) | ||
| 24 | { | 25 | { |
| 25 | } | 26 | } |
| 26 | 27 | ||
| @@ -31,6 +32,7 @@ void EmuThread::SetFilename(std::string filename) | |||
| 31 | 32 | ||
| 32 | void EmuThread::run() | 33 | void EmuThread::run() |
| 33 | { | 34 | { |
| 35 | stop_run = false; | ||
| 34 | while (true) | 36 | while (true) |
| 35 | { | 37 | { |
| 36 | for (int tight_loop = 0; tight_loop < 10000; ++tight_loop) | 38 | for (int tight_loop = 0; tight_loop < 10000; ++tight_loop) |
| @@ -41,11 +43,17 @@ void EmuThread::run() | |||
| 41 | exec_cpu_step = false; | 43 | exec_cpu_step = false; |
| 42 | 44 | ||
| 43 | Core::SingleStep(); | 45 | Core::SingleStep(); |
| 44 | if (!cpu_running) | 46 | if (!cpu_running) { |
| 45 | emit CPUStepped(); | 47 | emit CPUStepped(); |
| 48 | yieldCurrentThread(); | ||
| 49 | } | ||
| 46 | } | 50 | } |
| 47 | } | 51 | } |
| 52 | QMutexLocker lock(&mutex); | ||
| 53 | if (stop_run) | ||
| 54 | break; | ||
| 48 | } | 55 | } |
| 56 | render_window->moveContext(); | ||
| 49 | 57 | ||
| 50 | Core::Stop(); | 58 | Core::Stop(); |
| 51 | } | 59 | } |
| @@ -58,16 +66,24 @@ void EmuThread::Stop() | |||
| 58 | return; | 66 | return; |
| 59 | } | 67 | } |
| 60 | 68 | ||
| 69 | { | ||
| 70 | QMutexLocker lock(&mutex); | ||
| 71 | stop_run = true; | ||
| 72 | } | ||
| 73 | |||
| 61 | //core::g_state = core::SYS_DIE; | 74 | //core::g_state = core::SYS_DIE; |
| 62 | 75 | ||
| 63 | wait(1000); | 76 | wait(500); |
| 64 | if (isRunning()) | 77 | if (isRunning()) |
| 65 | { | 78 | { |
| 66 | WARN_LOG(MASTER_LOG, "EmuThread still running, terminating..."); | 79 | WARN_LOG(MASTER_LOG, "EmuThread still running, terminating..."); |
| 67 | terminate(); | 80 | quit(); |
| 68 | wait(1000); | 81 | wait(1000); |
| 69 | if (isRunning()) | 82 | if (isRunning()) |
| 83 | { | ||
| 70 | WARN_LOG(MASTER_LOG, "EmuThread STILL running, something is wrong here..."); | 84 | WARN_LOG(MASTER_LOG, "EmuThread STILL running, something is wrong here..."); |
| 85 | terminate(); | ||
| 86 | } | ||
| 71 | } | 87 | } |
| 72 | INFO_LOG(MASTER_LOG, "EmuThread stopped"); | 88 | INFO_LOG(MASTER_LOG, "EmuThread stopped"); |
| 73 | } | 89 | } |
| @@ -116,7 +132,6 @@ GRenderWindow::GRenderWindow(QWidget* parent) : QWidget(parent), emu_thread(this | |||
| 116 | layout->setMargin(0); | 132 | layout->setMargin(0); |
| 117 | setLayout(layout); | 133 | setLayout(layout); |
| 118 | QObject::connect(&emu_thread, SIGNAL(started()), this, SLOT(moveContext())); | 134 | QObject::connect(&emu_thread, SIGNAL(started()), this, SLOT(moveContext())); |
| 119 | QObject::connect(&emu_thread, SIGNAL(finished()), this, SLOT(moveContext())); | ||
| 120 | 135 | ||
| 121 | BackupGeometry(); | 136 | BackupGeometry(); |
| 122 | } | 137 | } |
| @@ -127,13 +142,14 @@ void GRenderWindow::moveContext() | |||
| 127 | // We need to move GL context to the swapping thread in Qt5 | 142 | // We need to move GL context to the swapping thread in Qt5 |
| 128 | #if QT_VERSION > QT_VERSION_CHECK(5, 0, 0) | 143 | #if QT_VERSION > QT_VERSION_CHECK(5, 0, 0) |
| 129 | // If the thread started running, move the GL Context to the new thread. Otherwise, move it back. | 144 | // If the thread started running, move the GL Context to the new thread. Otherwise, move it back. |
| 130 | child->context()->moveToThread(emu_thread.isRunning() ? &emu_thread : qApp->thread()); | 145 | child->context()->moveToThread((QThread::currentThread() == qApp->thread()) ? &emu_thread : qApp->thread()); |
| 131 | #endif | 146 | #endif |
| 132 | } | 147 | } |
| 133 | 148 | ||
| 134 | GRenderWindow::~GRenderWindow() | 149 | GRenderWindow::~GRenderWindow() |
| 135 | { | 150 | { |
| 136 | emu_thread.Stop(); | 151 | if (emu_thread.isRunning()) |
| 152 | emu_thread.Stop(); | ||
| 137 | } | 153 | } |
| 138 | 154 | ||
| 139 | void GRenderWindow::SwapBuffers() | 155 | void GRenderWindow::SwapBuffers() |
| @@ -144,7 +160,8 @@ void GRenderWindow::SwapBuffers() | |||
| 144 | 160 | ||
| 145 | void GRenderWindow::closeEvent(QCloseEvent* event) | 161 | void GRenderWindow::closeEvent(QCloseEvent* event) |
| 146 | { | 162 | { |
| 147 | emu_thread.Stop(); | 163 | if (emu_thread.isRunning()) |
| 164 | emu_thread.Stop(); | ||
| 148 | QWidget::closeEvent(event); | 165 | QWidget::closeEvent(event); |
| 149 | } | 166 | } |
| 150 | 167 | ||