summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAssam Boudjelthia <[email protected]>2023-11-25 12:57:31 +0200
committerAssam Boudjelthia <[email protected]>2023-12-02 17:56:37 +0000
commit1c1f5f5cb1e6da8fdf9503e5f46a88bf03c5baeb (patch)
tree609704b04d5b0d05b8e84f997a55b3373649c387
parentc81a9e4ed6a9d667e1d0ff4687416ee19860e0d0 (diff)
AndroidTestRunner: fix failure to acquire test runner semaphore
Currently, if the test runner is interrupted by SIGINT and SIGTERM, the semaphore is never released and thus consecutive test runner executions will wait forever. To fix that, a signal handler for the former signals is added to release the QSystemSemaphore. Also, remove RunnerLocker and simply use QSystemSemaphore directly, and explicitly release the semaphore at the end of the test runner execution. Fixes: QTBUG-115298 Change-Id: I4f6cc0e4d837460de9a66248e09d3cbaf24ce959 Reviewed-by: Axel Spoerl <[email protected]> Reviewed-by: Zoltan Gera <[email protected]> (cherry picked from commit 20643d17bfe6266ff6582c944ccd9d35fbbe5048) Reviewed-by: Qt Cherry-pick Bot <[email protected]> (cherry picked from commit ca80d4ff091245d20f4f19c0b0f7dc880e52d112) Reviewed-by: Qt CI Bot <[email protected]>
-rw-r--r--src/tools/androidtestrunner/main.cpp54
1 files changed, 40 insertions, 14 deletions
diff --git a/src/tools/androidtestrunner/main.cpp b/src/tools/androidtestrunner/main.cpp
index 4d53f74f19c..79a865e6c86 100644
--- a/src/tools/androidtestrunner/main.cpp
+++ b/src/tools/androidtestrunner/main.cpp
@@ -11,6 +11,8 @@
#include <algorithm>
#include <functional>
+#include <atomic>
+#include <csignal>
#include <QtCore/QDeadlineTimer>
#include <QtCore/QThread>
#include <QtCore/QProcessEnvironment>
@@ -514,19 +516,6 @@ static bool pullFiles()
return ret;
}
-struct RunnerLocker
-{
- RunnerLocker()
- {
- runner.acquire();
- }
- ~RunnerLocker()
- {
- runner.release();
- }
- QSystemSemaphore runner{QStringLiteral("androidtestrunner"), 1, QSystemSemaphore::Open};
-};
-
void printLogcat(const QString &formattedTime)
{
QString logcatCmd = "%1 logcat "_L1.arg(g_options.adbCommand);
@@ -618,8 +607,40 @@ static QString getCurrentTimeString()
return QString::fromUtf8(output.simplified());
}
+struct TestRunnerSystemSemaphore
+{
+ TestRunnerSystemSemaphore() { }
+ ~TestRunnerSystemSemaphore() { release(); }
+
+ void acquire() { isAcquired.store(semaphore.acquire()); }
+
+ void release()
+ {
+ bool expected = true;
+ // NOTE: There's still could be tiny time gap between the compare_exchange_strong() call
+ // and release() call where the thread could be interrupted, if that's ever an issue,
+ // this code could be checked and improved further.
+ if (isAcquired.compare_exchange_strong(expected, false))
+ isAcquired.store(!semaphore.release());
+ }
+
+ std::atomic<bool> isAcquired { false };
+ QSystemSemaphore semaphore { QStringLiteral("androidtestrunner"), 1, QSystemSemaphore::Open };
+};
+
+TestRunnerSystemSemaphore testRunnerLock;
+
+void sigHandler(int signal)
+{
+ std::signal(signal, SIG_DFL);
+ testRunnerLock.release();
+}
+
int main(int argc, char *argv[])
{
+ std::signal(SIGINT, sigHandler);
+ std::signal(SIGTERM, sigHandler);
+
QCoreApplication a(argc, argv);
if (!parseOptions()) {
printHelp();
@@ -657,7 +678,9 @@ int main(int argc, char *argv[])
obtainSDKVersion();
- RunnerLocker lock; // do not install or run packages while another test is running
+ // do not install or run packages while another test is running
+ testRunnerLock.acquire();
+
if (!execCommand(QStringLiteral("%1 install -r -g %2")
.arg(g_options.adbCommand, g_options.apkPath), nullptr, g_options.verbose)) {
return 1;
@@ -695,5 +718,8 @@ int main(int argc, char *argv[])
res &= execCommand(QStringLiteral("%1 uninstall %2").arg(g_options.adbCommand, g_options.package),
nullptr, g_options.verbose);
fflush(stdout);
+
+ testRunnerLock.release();
+
return res ? 0 : 1;
}