Adapt all callers' code so that it passes the FilePath
instead of QString. As a consequence introduce
TemporaryDirectory::masterDirectoryFilePath() and use
it where easily possible.
Change-Id: I14564949b3b916921e32a2957c84c03d1da43af2
Reviewed-by: hjk <hjk@qt.io>
It may apparently happen that when calling QProcess::start()
we may receive a synchronous signal QProcess::errorOccurred()
from the process we are trying to start. In this case
the handler of the error signal might have removed the
process from m_processes hash, which invalidated the
"Process *& process" reference inside
LauncherSocketHandler::handleStartPacket(). So, using
process reference after calling start() may be dangerous.
Refactor ProcessStartHandler so that it stores the pointer
to the process it handles. The pointer to the handler
should still be valid after calling start(), since
the process itself is being deleted with a delay.
Make ProcessStartHandler a member of ProcessHelper. In this
way it's being reused in QProcessImpl and ProcessLauncher.
Fixes: QTCREATORBUG-26726
Change-Id: I8e3f39953035d76c83bbbb13bd78e3042ba2a14e
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Still trying to ramp down non-QtcProcess interfaces.
Change-Id: I6b4ae6788f5021959ff3eb35bbade2157a6d67fa
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
Before the m_startFailure flag was used to detect the case
when the process failed to start because of wrong filename.
As this flag was set on any possible error we have always
detected the wrong filename case. Replace this flag with a
new enum describing various start failures.
Don't report again the crashed message. Check if we have already
reported the stop and we don't report it again. The
processExited() handler is being called twice: directly from
localGuiProcessError() and through the delayed localProcessDone().
Fixes: QTCREATORBUG-26467
Change-Id: I3cc6aa0c0b702256cefd77ba95793cd31e82ae10
Reviewed-by: hjk <hjk@qt.io>
These two objects are only used when QtcProcess::runBlocking()
with m_processUserEvents option set is called, otherwise
they are unused. Create them only when they are needed.
This also solves the issue that these two QObjects were not
moved together with QtcProcess when it was moved to another
thread.
Change-Id: I7de6a92a51fc249184fc5811dac7a7bbf05d351f
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: hjk <hjk@qt.io>
The goal is to make a QtcProcess incl. environment, working directory,
executable and arguments testable, e.g. in a terminal. The new
toStandaloneCommandLine() returns a string containing the command line
for a call of "env" the data of the QtcProcess instance as parameters.
To be used like:
qDebug().noquote() << qtcProc.toStandaloneCommandLine();
..and the debug output can be pasted into a terminal.
Change-Id: Ib6cbea290e1eff3279d6e0a67076a624312af879
Reviewed-by: hjk <hjk@qt.io>
There was already a similar function taking a QString.
After that, the remaining no-argument version of absolutePath()
can be deprecated.
Change-Id: I5b9ad8c8b68a5723891b0aa9f5a37e90db0fe09e
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: David Schulz <david.schulz@qt.io>
Reuse ProcessReaper inside process launcher.
Automatically reap all internal QProcesses of QtcProcess
(either direct child of QtcProcess in QProcessImpl
or indirectly inside process launcher).
Make ProcessReaper work again on QProcess instead of on
QtcProcess, so it may still be reused for non-QtcProcesses.
Change-Id: I950cac5cec28f17ae97fe474d6a4e48c01d6aaa2
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: hjk <hjk@qt.io>
Sometimes after creating QtcProcess we move it into a different
thread. In this case we should move all the children, too.
Without parent-child relation all the children will stay in the
old thread.
Change-Id: Ibde44d6153092a155dd2d200a7116a046910dddc
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Measure it on demand. The printout will appear when
QTC_MEASURE_PROCESS env variable is set. It may be easily
combined with QTC_USE_QPROCESS to compare the time spent
on freezing Creator when starting Creator or when loading
a big project, like Creator project.
In order to compare the measurement between
old implementation (using directly QProcess) and
new implementation (using process launcher) of QtcProcess
do the following (linux):
1. To measure the new implementation:
QTC_MEASURE_PROCESS= ./bin/qtcreator
2. To measure the old implementation:
QTC_USE_QPROCESS= QTC_MEASURE_PROCESS= ./bin/qtcreator
How to measure (two scenarios, A and B):
A. Launch Creator (don't load any project), wait a bit
until all processes finished. Look for the last value
in the 11th column ([A/M] Total Measurement, A means
all measured functions, M means in main thread only).
This value has the greatest influence on GUI freeze -
the higher it is, the longer the GUI is frozen.
Measure it with 1. (new) and 2. (old) implementation
and share your results.
B. Launch Creator and load a Creator project.
Wait until all processes finished (taskbar should be empty).
Look for the last value in the 11th column.
Measure it with 1. (new) and 2. (old) implementation
and share your results.
C* (Additional one)
If only you notice that launching a certain QtcProcess takes
suspiciously too long, replay your scenario that triggers
this process with 1. and 2. and share your results of
the 11th column.
Change-Id: I549c0a9fd0b3d6223f3d27288130553d99ab768e
Reviewed-by: David Schulz <david.schulz@qt.io>
Reviewed-by: hjk <hjk@qt.io>
Instead of returning a pointer to LauncherSocket instance,
which might get deleted in meantime of just after,
route all calls to the LauncherSocket through the LauncherInterface.
Make all calls to LauncherInterface secured by the
instance mutex.
Change-Id: I751228de5f4263112471098ee08cc73a5245147e
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Since e755094480 we have a global option
in Qt Creator to set the (base) environment for any tools run by Qt
Creator. So it is expected that any tool actually uses
Environment::systemEnvironment() as a base, which is the system
environment modified by the global option.
QtcProcess already had a fallback to Environment::systemEnvironment for
resolving environment variables in Qt Creator macros in the command
line. Also use it as a fallback for the actual environment for the
process.
Latest occurrence where the global environment setting was ignored was
for starting language servers by our LSP client.
Change-Id: Id1a4141326d8ef3239b37d7f3daf21928605ca92
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
Fix a race condition in the following scenario:
QtcProcess proc(...)
...
proc.start();
proc.waitForStarted();
if (!proc.waitForFinished()) {
// handle failure here
return;
}
// handle success
Move all the data into the caller's handle
and manage the QtcProcess state only from
inside caller's thread. This eliminates race
conditions when state changed from inside launcher's
thread while the caller's thread isn't notified
immediately.
For example: currently, when the launcher's thread receives
finished signal it doesn't change the process state
immediately, but posts a finished signal to be
dispatched in the caller's thread. When the caller's
thread dispatches the posted signal (inside flush() method)
it changes its state and posts the finished signal to the
outside world.
Don't flush all signals from waitForStarted(). Flush
only started signal in this case.
Change-Id: Ia39c4021bf43b8d0e8fcda789c367c096bfd032c
Reviewed-by: hjk <hjk@qt.io>
A convenience wrapper around QProcess::startDetached().
Change-Id: If4228e8405ad4d5e172930593a6f670874211767
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Add some developer comments explaining which method
is designed to be called from a certain thread.
Add also some comments about in which thread
certain QObjects live in.
Change-Id: I38b10216cc29f8a86fd784e588e913407f0fb776
Reviewed-by: hjk <hjk@qt.io>
All the uses of setStd{Out,Err}Callback in the codebase call proc.stdOut/
stdErr after the execution.
This triggered a soft assertion that was apparently not noticed so far.
It broke for example prompt for conflict resolution on Git pull/rebase.
Change-Id: Ib4b8301f1f50b2b66f02fc4dc6c14d93f895ea33
Reviewed-by: hjk <hjk@qt.io>
Similar to QT_RESTRICTED_CAST_FROM_ASCII to avoid the need for
decorations in user code.
At the same time, drop some convenience constructors and functions
in CommandLine and Icon essentially serving the same purpose.
Change-Id: Ida4e5ac19c2da0a4298a97b2a8e1511d56bbb79d
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Use QTC_USE_QPROCESS env var to switch back to the original
implementation based on direct use of QProcess. By default
a new implementation employing process launcher will be used.
Change-Id: I75c3efb579e26de377fc785404f1e2a08367d994
Reviewed-by: hjk <hjk@qt.io>
The previous tighter check is actually good theoretically, but currently
ShellCommand::runFullySynchronous triggers it and disentangling there
is not trivial. So weaken it a bit for now to not annoy users.
Change-Id: Ifc6b5713b398db0af0f604834c37ff361c2a1ed3
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Remove setCreateProcessArgumentModifier() from the ProcessInterface
API and replace it with belowNormalPriority flag.
Change-Id: I6bcb92e56c3a68af7fa3e3a1c8b8eb13e3a2e5a7
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: hjk <hjk@qt.io>
This patch needs to be applied together with the parent change.
There are 3 basic cases:
1. The user doesn't write anything to the write channel:
You don't need to call closeWriteChannel manually anymore.
By default the QtcProcess you create is in ProcessMode::Reader mode.
Internally it opens the process in ReadOnly mode and
closes the write channel just after starting.
2. The user writes some initial data (after being started)
and then closes the write channel:
All what is needed now it to set the write data
(QtcProcess::setWriteData) before calling start.
You also use the default ProcessMode::Reader mode.
Internally it opens the process in ReadWrite mode
and writes the writeData asynchonously when the process
already started. After writing the data it closes the
write channel automatically.
3. The user writes the data also after calling start.
All you need now is to create a process with
ProcessMode::Writer mode. In this mode the write
channel is not closed.
Internally it opens the process in ReadWrite mode
as some writers also read the data from the process.
All the code base is adapted here to the above rules.
Change-Id: Id103019d1d71a3012fd1eade226fe96b9aaa48c2
Reviewed-by: hjk <hjk@qt.io>
Don't base process token on instance pointer,
as it may happen that the recreated instance may
get the same token again (it happens often when invoking
a function that recreates QtcProcess in sequence).
The consequence may be that on the project launcher side
we may reuse the old process (with possibly broken state)
instead of creating a new one.
Change-Id: I8274691f88ae0eefe008746d944a26f29979bf72
Reviewed-by: hjk <hjk@qt.io>
The internal handling of output gets in the way when trying
to read output from a process synchronously.
Make usage of the internal one instead of relying on the
original output handling.
Fixes: QTCREATORBUG-25958
Change-Id: Ie96b5e8d17799a613ff15a52a23a8bdc31cb2939
Reviewed-by: hjk <hjk@qt.io>