From 139a5eb49630749c10de44841a6a97aea3c12a8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vr=C3=A1til?= Date: Wed, 28 Feb 2024 23:21:12 +0100 Subject: [PATCH 1/2] Fix coroutine being resumed on a wrong thread after timeout When awaiting a signal emission with qCoro() would time out, we would resume the awaiting coroutine in the context of the thread in which the emitter lives instead of the thread in which qCoro() was called from. Fixes #213 --- qcoro/core/qcorosignal.h | 2 +- tests/qcorosignal.cpp | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/qcoro/core/qcorosignal.h b/qcoro/core/qcorosignal.h index 3d3b927..d68586c 100644 --- a/qcoro/core/qcorosignal.h +++ b/qcoro/core/qcorosignal.h @@ -114,7 +114,7 @@ class QCoroSignalBase { [this, awaitingCoroutine]() { QObject::disconnect(mConn); awaitingCoroutine.resume(); - }); + }, Qt::DirectConnection); // force coro to be resumed on our thread, not mObj's thread mTimeoutTimer->start(); } } diff --git a/tests/qcorosignal.cpp b/tests/qcorosignal.cpp index 6d56f2a..e9b339b 100644 --- a/tests/qcorosignal.cpp +++ b/tests/qcorosignal.cpp @@ -36,6 +36,8 @@ class SignalTest : public QObject { void privateVoid(QPrivateSignal); void privateSingleArg(const QString &, QPrivateSignal); void privateMultiArg(const QString &, int, QObject *, QPrivateSignal); + + void signalThatsNeverEmitted(); }; class MultiSignalTest : public SignalTest { @@ -394,6 +396,24 @@ class QCoroSignalTest : public QCoro::TestObject { QCORO_COMPARE(count, 10); } + QCoro::Task<> testSignalEmitterOnDifferentThread_coro(QCoro::TestContext) { + SignalTest test; + QThread thread; + test.moveToThread(&thread); + thread.start(); + + co_await qCoro(&test, &SignalTest::voidSignal); + // Make sure we are resumed on our thread + QCORO_COMPARE(QThread::currentThread(), qApp->thread()); + + co_await qCoro(&test, &SignalTest::signalThatsNeverEmitted, 20ms); + // Make sure we are resumed on our thread after the timeout + QCORO_COMPARE(QThread::currentThread(), qApp->thread()); + + thread.quit(); + thread.wait(); + } + private Q_SLOTS: addTest(Triggers) addTest(ReturnsValue) @@ -420,6 +440,7 @@ private Q_SLOTS: addTest(SignalListenerQPrivateSignalVoid) addTest(SignalListenerQPrivateSignalValue) addTest(SignalListenerQPrivateSignalTuple) + addTest(SignalEmitterOnDifferentThread) }; QTEST_GUILESS_MAIN(QCoroSignalTest) From 154fe25c3b12083b16e71c777d8b127073476dc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vr=C3=A1til?= Date: Fri, 1 Mar 2024 21:14:07 +0100 Subject: [PATCH 2/2] Fix QCoroSignal test build on Qt5 --- tests/qcorosignal.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/qcorosignal.cpp b/tests/qcorosignal.cpp index e9b339b..cfbf92d 100644 --- a/tests/qcorosignal.cpp +++ b/tests/qcorosignal.cpp @@ -8,6 +8,7 @@ #include "qcoro/core/qcorosignal.h" #include +#include using namespace std::chrono_literals;