mirror of
https://github.com/Mahdi-zarei/nekoray.git
synced 2025-12-19 13:50:12 +08:00
Fix threading issues
This commit is contained in:
parent
16d951eed1
commit
546b023dbc
@ -167,11 +167,11 @@ void ActivateWindow(QWidget *w);
|
|||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
void runOnUiThread(const std::function<void()> &callback);
|
void runOnUiThread(const std::function<void()> &callback, bool wait = false);
|
||||||
|
|
||||||
void runOnNewThread(const std::function<void()> &callback);
|
void runOnNewThread(const std::function<void()> &callback, bool wait = false);
|
||||||
|
|
||||||
void runOnThread(const std::function<void()> &callback, QObject *parent);
|
void runOnThread(const std::function<void()> &callback, QObject *parent, bool wait = false);
|
||||||
|
|
||||||
template<typename EMITTER, typename SIGNAL, typename RECEIVER, typename ReceiverFunc>
|
template<typename EMITTER, typename SIGNAL, typename RECEIVER, typename ReceiverFunc>
|
||||||
inline void connectOnce(EMITTER *emitter, SIGNAL signal, RECEIVER *receiver, ReceiverFunc f,
|
inline void connectOnce(EMITTER *emitter, SIGNAL signal, RECEIVER *receiver, ReceiverFunc f,
|
||||||
|
|||||||
@ -249,38 +249,84 @@ void ActivateWindow(QWidget *w) {
|
|||||||
w->activateWindow();
|
w->activateWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void runOnUiThread(const std::function<void()> &callback) {
|
void runOnUiThread(const std::function<void()> &callback, bool wait) {
|
||||||
// any thread
|
// any thread
|
||||||
auto *timer = new QTimer();
|
auto *timer = new QTimer();
|
||||||
auto thread = mainwindow->thread();
|
auto thread = mainwindow->thread();
|
||||||
timer->moveToThread(thread);
|
timer->moveToThread(thread);
|
||||||
timer->setSingleShot(true);
|
timer->setSingleShot(true);
|
||||||
QObject::connect(timer, &QTimer::timeout, [=]() {
|
|
||||||
|
QEventLoop loop;
|
||||||
|
QObject::connect(timer, &QTimer::timeout, [=, &loop]() {
|
||||||
// main thread
|
// main thread
|
||||||
callback();
|
callback();
|
||||||
timer->deleteLater();
|
timer->deleteLater();
|
||||||
|
|
||||||
|
if (wait)
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(&loop, "quit", Qt::QueuedConnection);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
QMetaObject::invokeMethod(timer, "start", Qt::QueuedConnection, Q_ARG(int, 0));
|
QMetaObject::invokeMethod(timer, "start", Qt::QueuedConnection, Q_ARG(int, 0));
|
||||||
|
|
||||||
|
if (wait && QThread::currentThread() != thread) {
|
||||||
|
loop.exec();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void runOnNewThread(const std::function<void()> &callback) {
|
void runOnNewThread(const std::function<void()> &callback, bool wait) {
|
||||||
createQThread(callback)->start();
|
auto *timer = new QTimer();
|
||||||
|
auto thread = new QThread();
|
||||||
|
timer->moveToThread(thread);
|
||||||
|
timer->setSingleShot(true);
|
||||||
|
|
||||||
|
thread->start();
|
||||||
|
QObject::connect(thread, &QThread::finished, thread, &QObject::deleteLater);
|
||||||
|
|
||||||
|
QEventLoop loop;
|
||||||
|
QObject::connect(timer, &QTimer::timeout, [=, &loop]() {
|
||||||
|
callback();
|
||||||
|
timer->deleteLater();
|
||||||
|
QMetaObject::invokeMethod(thread, "quit", Qt::QueuedConnection);
|
||||||
|
|
||||||
|
if (wait)
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(&loop, "quit", Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
QMetaObject::invokeMethod(timer, "start", Qt::QueuedConnection, Q_ARG(int, 0));
|
||||||
|
|
||||||
|
if (wait && QThread::currentThread() != thread) {
|
||||||
|
loop.exec();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void runOnThread(const std::function<void()> &callback, QObject *parent) {
|
void runOnThread(const std::function<void()> &callback, QObject *parent, bool wait) {
|
||||||
auto *timer = new QTimer();
|
auto *timer = new QTimer();
|
||||||
auto thread = dynamic_cast<QThread *>(parent);
|
auto thread = dynamic_cast<QThread *>(parent);
|
||||||
if (thread == nullptr) {
|
if (thread == nullptr) {
|
||||||
timer->moveToThread(parent->thread());
|
timer->moveToThread(parent->thread());
|
||||||
|
thread = parent->thread();
|
||||||
} else {
|
} else {
|
||||||
timer->moveToThread(thread);
|
timer->moveToThread(thread);
|
||||||
}
|
}
|
||||||
timer->setSingleShot(true);
|
timer->setSingleShot(true);
|
||||||
QObject::connect(timer, &QTimer::timeout, [=]() {
|
|
||||||
|
QEventLoop loop;
|
||||||
|
QObject::connect(timer, &QTimer::timeout, [=, &loop]() {
|
||||||
callback();
|
callback();
|
||||||
timer->deleteLater();
|
timer->deleteLater();
|
||||||
|
|
||||||
|
if (wait)
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(&loop, "quit", Qt::QueuedConnection);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
QMetaObject::invokeMethod(timer, "start", Qt::QueuedConnection, Q_ARG(int, 0));
|
QMetaObject::invokeMethod(timer, "start", Qt::QueuedConnection, Q_ARG(int, 0));
|
||||||
|
|
||||||
|
if (wait && QThread::currentThread() != thread) {
|
||||||
|
loop.exec();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTimeout(const std::function<void()> &callback, QObject *obj, int timeout) {
|
void setTimeout(const std::function<void()> &callback, QObject *obj, int timeout) {
|
||||||
|
|||||||
@ -62,7 +62,10 @@ namespace Configs_sys {
|
|||||||
if (restarting) return;
|
if (restarting) return;
|
||||||
|
|
||||||
MW_show_log("[Fatal] " + QObject::tr("Core exited, cleaning up..."));
|
MW_show_log("[Fatal] " + QObject::tr("Core exited, cleaning up..."));
|
||||||
GetMainWindow()->profile_stop(true, true);
|
runOnUiThread([=, this]
|
||||||
|
{
|
||||||
|
GetMainWindow()->profile_stop(true, true);
|
||||||
|
}, true);
|
||||||
|
|
||||||
// Retry rate limit
|
// Retry rate limit
|
||||||
if (coreRestartTimer.isValid()) {
|
if (coreRestartTimer.isValid()) {
|
||||||
|
|||||||
@ -570,7 +570,10 @@ void MainWindow::profile_start(int _id) {
|
|||||||
runOnNewThread([=, this] {
|
runOnNewThread([=, this] {
|
||||||
// stop current running
|
// stop current running
|
||||||
if (running != nullptr) {
|
if (running != nullptr) {
|
||||||
profile_stop(false, true, true);
|
runOnUiThread([=, this]
|
||||||
|
{
|
||||||
|
profile_stop(false, true, true);
|
||||||
|
}, true);
|
||||||
}
|
}
|
||||||
// do start
|
// do start
|
||||||
MW_show_log(">>>>>>>> " + tr("Starting profile %1").arg(ent->bean->DisplayTypeAndName()));
|
MW_show_log(">>>>>>>> " + tr("Starting profile %1").arg(ent->bean->DisplayTypeAndName()));
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user