diff --git a/src/tools/androidtestrunner/main.cpp b/src/tools/androidtestrunner/main.cpp index c88c19bac52..defa7500aea 100644 --- a/src/tools/androidtestrunner/main.cpp +++ b/src/tools/androidtestrunner/main.cpp @@ -11,6 +11,8 @@ #include #include +#include +#include #include #include #include @@ -512,20 +514,6 @@ static bool pullFiles() return ret; } -struct RunnerLocker -{ - RunnerLocker() - { - runner.acquire(); - } - ~RunnerLocker() - { - runner.release(); - } - QSystemSemaphore runner{ QSystemSemaphore::platformSafeKey(u"androidtestrunner"_s), - 1, QSystemSemaphore::Open }; -}; - void printLogcat(const QString &formattedTime) { QString logcatCmd = "%1 logcat "_L1.arg(g_options.adbCommand); @@ -617,8 +605,41 @@ 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 isAcquired { false }; + QSystemSemaphore semaphore { QSystemSemaphore::platformSafeKey(u"androidtestrunner"_s), + 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(); @@ -656,7 +677,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; @@ -694,5 +717,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; }