diff --git a/OSBindings/Qt/functionthread.h b/OSBindings/Qt/functionthread.h index 63e237547..759338277 100644 --- a/OSBindings/Qt/functionthread.h +++ b/OSBindings/Qt/functionthread.h @@ -24,6 +24,11 @@ class FunctionThread: public QThread { exec(); } + void stop() { + QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection); + while(isRunning()); + } + private: std::function function; }; diff --git a/OSBindings/Qt/mainwindow.cpp b/OSBindings/Qt/mainwindow.cpp index 7956c61f4..18f6b292e 100644 --- a/OSBindings/Qt/mainwindow.cpp +++ b/OSBindings/Qt/mainwindow.cpp @@ -66,9 +66,7 @@ MainWindow::~MainWindow() { // Stop the audio output, and its thread. if(audioOutput) { audioOutput->stop(); - - audioThread.quit(); - while(audioThread.isRunning()); + audioThread.stop(); } // Stop the timer. diff --git a/OSBindings/Qt/timer.cpp b/OSBindings/Qt/timer.cpp index c50e903b3..9c9a0fa25 100644 --- a/OSBindings/Qt/timer.cpp +++ b/OSBindings/Qt/timer.cpp @@ -10,7 +10,7 @@ Timer::Timer(QObject *parent) : QObject(parent) { // Set up the emulation timer. Bluffer's guide: the QTimer will post an // event to an event loop. QThread is a thread with an event loop. // My class, Timer, will be wired up to receive the QTimer's events. - timer = std::make_unique(&thread); + timer = std::make_unique(); timer->setInterval(1); connect(timer.get(), SIGNAL(timeout()), this, SLOT(tick()), Qt::DirectConnection); @@ -28,7 +28,6 @@ void Timer::startWithMachine(MachineTypes::TimedMachine *machine, std::mutex *ma void Timer::tick() { const auto now = Time::nanos_now(); const auto duration = std::min(now - lastTickNanos, int64_t(500'000'000)); -// qDebug() << duration << " [not " << now - lastTickNanos << "]"; lastTickNanos = now; std::lock_guard lock_guard(*machineMutex); @@ -36,8 +35,6 @@ void Timer::tick() { } Timer::~Timer() { - // Stop the timer, then ask the QThread to exit and wait for it to do so. - timer->stop(); - thread.exit(); - while(thread.isRunning()); + QMetaObject::invokeMethod(timer.get(), "stop", Qt::QueuedConnection); + thread.stop(); }