diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index 555a44a8a58..ed78b8f30b6 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -756,6 +756,7 @@ bool DebuggerRunTool::isQmlDebugging() const void DebuggerRunTool::setUsePortsGatherer(bool useCpp, bool useQml) { QTC_ASSERT(!d->portsGatherer, reportFailure(); return); + runControl()->enablePortsGatherer(); d->portsGatherer = new DebugServerPortsGatherer(runControl()); d->portsGatherer->setUseGdbServer(useCpp); d->portsGatherer->setUseQmlServer(useQml); @@ -1040,9 +1041,8 @@ namespace Internal { class SubChannelProvider : public RunWorker { public: - SubChannelProvider(RunControl *runControl, PortsGatherer *portsGatherer) + SubChannelProvider(RunControl *runControl) : RunWorker(runControl) - , m_portGatherer(portsGatherer) { setId("SubChannelProvider"); } @@ -1054,8 +1054,7 @@ public: m_channel.setHost("localhost"); else m_channel.setHost(device()->toolControlChannel(IDevice::ControlChannelHint()).host()); - if (m_portGatherer) - m_channel.setPort(m_portGatherer->findEndPoint().port()); + m_channel.setPort(runControl()->findEndPoint().port()); reportStarted(); } @@ -1063,7 +1062,6 @@ public: private: QUrl m_channel; - PortsGatherer *m_portGatherer = nullptr; }; } // Internal @@ -1108,12 +1106,11 @@ DebugServerPortsGatherer::DebugServerPortsGatherer(RunControl *runControl) : RunWorker(runControl) { setId("DebugServerPortsGatherer"); - auto portsGatherer = new PortsGatherer(runControl); - m_gdbChannelProvider = new Internal::SubChannelProvider(runControl, portsGatherer); + m_gdbChannelProvider = new Internal::SubChannelProvider(runControl); addStartDependency(m_gdbChannelProvider); - m_qmlChannelProvider = new Internal::SubChannelProvider(runControl, portsGatherer); + m_qmlChannelProvider = new Internal::SubChannelProvider(runControl); addStartDependency(m_qmlChannelProvider); } diff --git a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp index abfbb099842..a6557c10c94 100644 --- a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp +++ b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp @@ -109,45 +109,4 @@ QString DeviceUsedPortsGatherer::errorString() const return d->m_errorString; } -// PortGatherer - -PortsGatherer::PortsGatherer(RunControl *runControl) - : RunWorker(runControl) -{ - setId("PortGatherer"); - - connect(&m_portsGatherer, &DeviceUsedPortsGatherer::done, this, [this](bool success) { - if (success) { - m_portList = device()->freePorts(); - appendMessage(Tr::tr("Found %n free ports.", nullptr, m_portList.count()), - NormalMessageFormat); - reportStarted(); - } else { - reportFailure(m_portsGatherer.errorString()); - } - }); -} - -void PortsGatherer::start() -{ - appendMessage(Tr::tr("Checking available ports..."), NormalMessageFormat); - m_portsGatherer.setDevice(device()); - m_portsGatherer.start(); -} - -QUrl PortsGatherer::findEndPoint() -{ - QUrl result; - result.setScheme(urlTcpScheme()); - result.setHost(device()->sshParameters().host()); - result.setPort(m_portList.getNextFreePort(m_portsGatherer.usedPorts()).number()); - return result; -} - -void PortsGatherer::stop() -{ - m_portsGatherer.stop(); - reportStopped(); -} - } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h index 0c08aadeb68..6d22610d187 100644 --- a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h +++ b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h @@ -50,24 +50,6 @@ public: void start() final { task()->start(); } }; -class PROJECTEXPLORER_EXPORT PortsGatherer : public RunWorker -{ - Q_OBJECT - -public: - explicit PortsGatherer(RunControl *runControl); - - QUrl findEndPoint(); - -protected: - void start() override; - void stop() override; - -private: - DeviceUsedPortsGatherer m_portsGatherer; - Utils::PortList m_portList; -}; - using DeviceUsedPortsGathererTask = CustomTask; } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/runcontrol.cpp b/src/plugins/projectexplorer/runcontrol.cpp index 23ff5d09e6c..0c863df0c51 100644 --- a/src/plugins/projectexplorer/runcontrol.cpp +++ b/src/plugins/projectexplorer/runcontrol.cpp @@ -7,8 +7,10 @@ #include "buildconfiguration.h" #include "customparser.h" #include "devicesupport/devicemanager.h" +#include "devicesupport/deviceusedportsgatherer.h" #include "devicesupport/idevice.h" #include "devicesupport/idevicefactory.h" +#include "devicesupport/sshparameters.h" #include "devicesupport/sshsettings.h" #include "kitaspects.h" #include "project.h" @@ -18,6 +20,7 @@ #include "projectexplorertr.h" #include "runconfigurationaspects.h" #include "target.h" +#include "utils/url.h" #include "windebuginterface.h" #include @@ -326,6 +329,7 @@ public: void debugMessage(const QString &msg) const; void initiateStart(); + void startPortsGathererIfNeededAndContinueStart(); void initiateReStart(); void continueStart(); void initiateStop(); @@ -348,6 +352,9 @@ public: RunControl *q; Id runMode; TaskTreeRunner m_taskTreeRunner; + + std::unique_ptr portsGatherer; + PortList portList; }; } // Internal @@ -552,7 +559,7 @@ void RunControlPrivate::initiateStart() setState(RunControlState::Starting); debugMessage("Queue: Starting"); - continueStart(); + startPortsGathererIfNeededAndContinueStart(); } void RunControlPrivate::initiateReStart() @@ -568,7 +575,45 @@ void RunControlPrivate::initiateReStart() setState(RunControlState::Starting); debugMessage("Queue: ReStarting"); - continueStart(); + startPortsGathererIfNeededAndContinueStart(); +} + +void RunControlPrivate::startPortsGathererIfNeededAndContinueStart() +{ + if (!portsGatherer) { + continueStart(); + return; + } + + connect(portsGatherer.get(), &DeviceUsedPortsGatherer::done, this, [this](bool success) { + if (success) { + portList = device->freePorts(); + q->appendMessage(Tr::tr("Found %n free ports.", nullptr, portList.count()) + '\n', + NormalMessageFormat); + continueStart(); + } else { + onWorkerFailed(nullptr, portsGatherer->errorString()); + } + }); + + q->appendMessage(Tr::tr("Checking available ports...") + '\n', NormalMessageFormat); + portsGatherer->setDevice(device); + portsGatherer->start(); +} + +void RunControl::enablePortsGatherer() +{ + d->portsGatherer = std::make_unique(); +} + +QUrl RunControl::findEndPoint() +{ + QTC_ASSERT(d->portsGatherer, return {}); + QUrl result; + result.setScheme(urlTcpScheme()); + result.setHost(device()->sshParameters().host()); + result.setPort(d->portList.getNextFreePort(d->portsGatherer->usedPorts()).number()); + return result; } void RunControlPrivate::continueStart() @@ -734,7 +779,8 @@ void RunControlPrivate::onWorkerStarted(RunWorker *worker) void RunControlPrivate::onWorkerFailed(RunWorker *worker, const QString &msg) { - worker->d->state = RunWorkerState::Done; + if (worker) + worker->d->state = RunWorkerState::Done; showError(msg); switch (state) { diff --git a/src/plugins/projectexplorer/runcontrol.h b/src/plugins/projectexplorer/runcontrol.h index 25b8424a483..dc00eb5102a 100644 --- a/src/plugins/projectexplorer/runcontrol.h +++ b/src/plugins/projectexplorer/runcontrol.h @@ -234,6 +234,9 @@ public: static bool canRun(Utils::Id runMode, Utils::Id deviceType, Utils::Id runConfigId); void postMessage(const QString &msg, Utils::OutputFormat format, bool appendNewLine = true); + void enablePortsGatherer(); + QUrl findEndPoint(); + signals: void appendMessage(const QString &msg, Utils::OutputFormat format); void aboutToStart(); diff --git a/src/plugins/qnx/qnxanalyzesupport.cpp b/src/plugins/qnx/qnxanalyzesupport.cpp index d21d0b44c02..91056f5759d 100644 --- a/src/plugins/qnx/qnxanalyzesupport.cpp +++ b/src/plugins/qnx/qnxanalyzesupport.cpp @@ -27,8 +27,7 @@ public: setId("QnxQmlProfilerSupport"); appendMessage(Tr::tr("Preparing remote side..."), LogMessageFormat); - auto portsGatherer = new PortsGatherer(runControl); - addStartDependency(portsGatherer); + runControl->enablePortsGatherer(); auto slog2InfoRunner = new Slog2InfoRunner(runControl); addStartDependency(slog2InfoRunner); @@ -37,8 +36,8 @@ public: profiler->addStartDependency(this); addStopDependency(profiler); - setStartModifier([this, portsGatherer, profiler] { - const QUrl serverUrl = portsGatherer->findEndPoint(); + setStartModifier([this, runControl, profiler] { + const QUrl serverUrl = runControl->findEndPoint(); profiler->recordData("QmlServerUrl", serverUrl); CommandLine cmd = commandLine(); diff --git a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp index ed55eb532ea..8bf85b571aa 100644 --- a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp +++ b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp @@ -50,19 +50,14 @@ public: { setId("RemoteLinuxQmlToolingSupport"); - auto portsGatherer = new PortsGatherer(runControl); - addStartDependency(portsGatherer); - - // The ports gatherer can safely be stopped once the process is running, even though it has to - // be started before. - addStopDependency(portsGatherer); + runControl->enablePortsGatherer(); auto runworker = runControl->createWorker(QmlDebug::runnerIdForRunMode(runControl->runMode())); runworker->addStartDependency(this); addStopDependency(runworker); - setStartModifier([this, runControl, portsGatherer, runworker] { - const QUrl serverUrl = portsGatherer->findEndPoint(); + setStartModifier([this, runControl, runworker] { + const QUrl serverUrl = runControl->findEndPoint(); runworker->recordData("QmlServerUrl", serverUrl); QmlDebug::QmlDebugServicesPreset services = QmlDebug::servicesForRunMode(runControl->runMode()); diff --git a/src/plugins/webassembly/webassemblyrunconfiguration.cpp b/src/plugins/webassembly/webassemblyrunconfiguration.cpp index 754becd50ae..664625669c6 100644 --- a/src/plugins/webassembly/webassemblyrunconfiguration.cpp +++ b/src/plugins/webassembly/webassemblyrunconfiguration.cpp @@ -205,16 +205,15 @@ public: EmrunRunWorker(RunControl *runControl) : SimpleTargetRunner(runControl) { - auto portsGatherer = new PortsGatherer(runControl); - addStartDependency(portsGatherer); + runControl->enablePortsGatherer(); - setStartModifier([this, runControl, portsGatherer] { + setStartModifier([this, runControl] { const QString browserId = runControl->aspectData()->currentBrowser; setCommandLine(emrunCommand(runControl->target(), runControl->buildKey(), browserId, - QString::number(portsGatherer->findEndPoint().port()))); + QString::number(runControl->findEndPoint().port()))); setEnvironment(runControl->buildEnvironment()); }); }