diff options
Diffstat (limited to 'src/sdk/main.cpp')
-rw-r--r-- | src/sdk/main.cpp | 64 |
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; |