summaryrefslogtreecommitdiffstats
path: root/src/sdk/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/sdk/main.cpp')
-rw-r--r--src/sdk/main.cpp64
1 files changed, 63 insertions, 1 deletions
diff --git a/src/sdk/main.cpp b/src/sdk/main.cpp
index a1e330299..abfc9dc5a 100644
--- a/src/sdk/main.cpp
+++ b/src/sdk/main.cpp
@@ -48,10 +48,13 @@
#include <QCommandLineParser>
#include <QDateTime>
#include <QNetworkProxyFactory>
+#include <QThread>
+#include <QThreadPool>
+#include <QDeadlineTimer>
#include <iostream>
-#if defined(Q_OS_MACOS) or defined(Q_OS_UNIX)
+#if defined(Q_OS_MACOS) || defined(Q_OS_UNIX)
# include <unistd.h>
# include <sys/types.h>
#endif
@@ -63,8 +66,47 @@
#define SHA "Installer Framework SHA1: " QUOTE(_GIT_SHA1_)
static const char PLACEHOLDER[32] = "MY_InstallerCreateDateTime_MY";
+#ifdef Q_OS_WIN
+static void cleanupUpdate(const CommandLineParser &parser, bool *exit)
+{
+ QString cleanupPath;
+ QString cleanupOption;
+ *exit = false;
+
+ if (parser.isSet(CommandLineOptions::scCleanupUpdate)) {
+ cleanupPath = parser.value(CommandLineOptions::scCleanupUpdate);
+ cleanupOption = CommandLineOptions::scCleanupUpdate;
+ } else if (parser.isSet(CommandLineOptions::scCleanupUpdateOnly)) {
+ cleanupPath = parser.value(CommandLineOptions::scCleanupUpdateOnly);
+ cleanupOption = CommandLineOptions::scCleanupUpdateOnly;
+ *exit = true;
+ }
+
+ if (cleanupOption.isEmpty())
+ return;
+
+ // Since Windows does not support that the maintenance tool deletes itself we
+ // remove the old executable here after update (as the new maintenance tool).
+ if (!cleanupPath.isEmpty()) {
+ QFile fileToRemove(cleanupPath);
+ // Give up after 120 seconds if the old process has not exited and released the file
+ QDeadlineTimer deadline(120000);
+ while (fileToRemove.exists() && !deadline.hasExpired()) {
+ if (fileToRemove.remove()) {
+ std::cout << "Removed leftover file: " << qPrintable(cleanupPath)
+ << " after update." << std::endl;
+ }
+ QThread::msleep(1000);
+ }
+ } else {
+ std::cout << "Invalid value for option " << qPrintable(cleanupOption);
+ }
+}
+#endif
+
int main(int argc, char *argv[])
{
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
if (!qEnvironmentVariableIsSet("QT_AUTO_SCREEN_SCALE_FACTOR")
&& !qEnvironmentVariableIsSet("QT_SCALE_FACTOR")
&& !qEnvironmentVariableIsSet("QT_SCREEN_SCALE_FACTORS")) {
@@ -73,6 +115,7 @@ int main(int argc, char *argv[])
#if defined(Q_OS_WIN)
QCoreApplication::setAttribute(Qt::AA_DisableWindowContextHelpButton);
#endif
+#endif
// increase maximum numbers of file descriptors
#if defined(Q_OS_MACOS)
QCoreApplication::setSetuidAllowed(true);
@@ -82,6 +125,13 @@ int main(int argc, char *argv[])
setrlimit(RLIMIT_NOFILE, &rl);
#endif
+ // Try to avoid running into situations where the application would hang due to "nested" blocking
+ // usage of the global threadpool that has only one thread available, i.e. main thread invokes
+ // QtConcurrent::run(&myFunction) and myFunction() calls QtConcurrent::blockingFiltered()
+ // for a container.
+ if (QThread::idealThreadCount() == 1)
+ QThreadPool::globalInstance()->setMaxThreadCount(2);
+
// We need to start either a command line application or a GUI application. Since we
// fail doing so at least on Linux while parsing the argument using a core application
// object and later starting the GUI application, we now parse the arguments first.
@@ -159,6 +209,15 @@ int main(int argc, char *argv[])
return help ? EXIT_SUCCESS : EXIT_FAILURE;
}
+#ifdef Q_OS_WIN
+ {
+ bool exit = false;
+ cleanupUpdate(parser, &exit);
+ if (exit)
+ return EXIT_SUCCESS;
+ }
+#endif
+
if (parser.isSet(CommandLineOptions::scStartServerLong)) {
const QStringList arguments = parser.value(CommandLineOptions::scStartServerLong)
.split(QLatin1Char(','), Qt::SkipEmptyParts);
@@ -282,6 +341,9 @@ int main(int argc, char *argv[])
} else if (parser.positionalArguments().contains(CommandLineOptions::scCreateOfflineShort)
|| parser.positionalArguments().contains(CommandLineOptions::scCreateOfflineLong)) {
return CommandLineInterface(argc, argv).createOfflineInstaller();
+ } else if (parser.positionalArguments().contains(CommandLineOptions::scClearCacheShort)
+ || parser.positionalArguments().contains(CommandLineOptions::scClearCacheLong)) {
+ return CommandLineInterface(argc, argv).clearLocalCache();
}
if (QInstaller::LoggingHandler::instance().isVerbose()) {
std::cout << VERSION << std::endl << BUILDDATE << std::endl << SHA << std::endl;