mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +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
					
				
					 2 changed files with 29 additions and 9 deletions
				
			
		|  | @ -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,13 +142,14 @@ 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() | ||||||
| { | { | ||||||
|     emu_thread.Stop(); |     if (emu_thread.isRunning()) | ||||||
|  |         emu_thread.Stop(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void GRenderWindow::SwapBuffers() | void GRenderWindow::SwapBuffers() | ||||||
|  | @ -144,7 +160,8 @@ void GRenderWindow::SwapBuffers() | ||||||
| 
 | 
 | ||||||
| void GRenderWindow::closeEvent(QCloseEvent* event) | void GRenderWindow::closeEvent(QCloseEvent* event) | ||||||
| { | { | ||||||
|     emu_thread.Stop(); |     if (emu_thread.isRunning()) | ||||||
|  |         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…
	
	Add table
		Add a link
		
	
		Reference in a new issue