Use Utils::Environment for of environment.
Use Utils::FilePath for workingDirectory.
Change-Id: I6b717139f8ff7ddbd629fb22cf816b2303fb5e6a
Reviewed-by: hjk <hjk@qt.io>
In case the user called waitForReadyRead() and we have
received the finished signal instead (without receiving
readyRead signals in meantime), we should interrupt
the wait and return false, since there is no point to
wait for future readyRead signals from not running process.
Change-Id: Ib4a770aea6ed562a5bef197eaa51b20c146842f0
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
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>
Remove the process in process launcher after error has appeared.
Remove unneeded stopStopProcedure as we are disconnecting from
process' signals inside removeProcess().
In order to behave as much similar to what QProcess does,
provide a test that:
- ensures the FailedToStart error is synchronously emitted
when waitForStarted is being executed
- ensures that process state is reset to NotRunning after
FailedToStart error
- 2nd call to start/waitForStarted doesn't block on
waitForStarted
Change-Id: I139354421d037739f1cc1a2685b66f1e5b6170c8
Reviewed-by: Christian Stenger <christian.stenger@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>
Move qDeleteAll into cpp file, as LauncherSignal is defined there.
Change-Id: I59ed1de2025c3f62196e1c676accf26b3fb813ac
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Assert that we are in NotRunning state when starting a process.
Otherwise we issue a warning and ignore the new call.
Change-Id: Ie8c007851aabb4b814c1fd49bc8d01f22eb1a563
Reviewed-by: hjk <hjk@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>
Get rid of <QtModule/qclass.h> style and use <QClass> directly,
like in all other places in Creator. Remove some unneeded
declarations.
Change-Id: I1b5630850c570e5d86df01a341f7352bc1971e48
Reviewed-by: hjk <hjk@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>
Pipe the error packet through the caller's handle and flush
it immediately if the caller was awaiting for any signal.
Stop awaiting for any signal when we have flushed error signal.
In this case return false from waitForSignal() method
in order to mimic the QProcess behavior.
Fixes: QTCREATORBUG-26136
Change-Id: Ie80b4a63bd19a6309d4791ad39a698bd91bb8967
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
In case when QtcProcess::start() is being called very early,
just after the launcher socket was started but not ready yet,
a start is being delayed. In this case doStart() isn't
called directly from the caller's thread, but it will be
invoked later from the launcher's thread, when the socket is ready.
In this case we may have a deadlock, since calling
doStart(), sendPacket(), sendData() and finally handleRequests()
results in a synchonous chain of calls in launcher's thread,
so the mutex locked in sendData() will block synchronous call to
handleRequests(). In order to fix it we unlock the mutex
in sendData() before calling handleRequests().
Change-Id: I6c13994d0b05b624567c75ffbd2ac7cc0d77df61
Reviewed-by: hjk <hjk@qt.io>
Fix "runBlockingStdOut" autotest for tst_qtcprocess.
This crazy case relies on the fact that a blocking
call to waitForFinished() lets ReadyRead signals to
be processed in meantime and the handler for ReadyRead
may terminate the process. However, when no handler
for ReadyRead canceled the process, the blocking call to
waitForFinished() should return to the awaiting state
for the remaining time. From the caller's side everything
happens during a blocking invocation of waitForFinished().
So, in order to behave like this we implement waitForSignal()
in a loop. After we have flushed all the pending signals
we check if we have flushed the signal we were awaiting for.
If so, we break the loop, otherwise we continue. In order
to detect the case when the cancel was called during flushing
we set the m_awaitingShouldContinue flag before flushing.
The cancel() method clears this flag. Then after flushing
we check if the flag was cleared - in this case we don't
continue awaiting.
We reset the m_waitingFor state always after wait condition
finishes awaiting. Before, we didn't reset it when the
wait condition timed out.
Change-Id: I210f446659cabfd89bdfdd1fc8e8396d9470effc
Reviewed-by: hjk <hjk@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>
Try to mimic the behavior of QProcess inside process launcher
as much as possible. After calling QtcProcess::kill() we send
StopProcessPacket to the process launcher - when we receive
it there we start reaping of the process itself and report
back the finished packet with a failure.
Remove canceled state from the LanucherHandle, as after
canceling the process we still need to handle the finished
(or others) signals - like in case of QProcess.
Change-Id: Id66b06449de06675a0ab6778e93e9782afea09d4
Reviewed-by: hjk <hjk@qt.io>
Instead of waiting for certain state we wait for
certain signal to be placed into the buffer.
No need for m_finished flag anymore, since we are
only interesting if the buffer contains the finished
signal. This will enable to implement waiting for
ready read properly, since no state is changed
in this case.
Change-Id: I4209da385b2e37de6f1897357e35c0ed0c9e4096
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
In this way the output and error channels
get handled while waitingFor* is being executed.
Change-Id: I8d3d81bd99fcfb7ddea7e98337e859446380055f
Reviewed-by: hjk <hjk@qt.io>
Move launcher process into a separate thread.
Implement blocking API by using wait condition
on the caller's side. Replay all collected
signals from the launcher's thread when leaving
waitingFor* state. In case we were not waiting
for anything deliver the signals asynchronously
from launcher's thread to the caller's thread.
Change-Id: Id44fe5f7ceaac407004984a1dfb6ea65f197d297
Reviewed-by: hjk <hjk@qt.io>
Implement the reply confirmation for the started signal.
After qtcreator_processlauncher starts a new process
we connect to its started() signal and post a reply through
the socket to the LauncherInterface with the information about
the new PID. ProcessLauncherImpl now emits the started signal
with a delay, just after the confirmation has been received.
Change-Id: I2689e8e97b17466bd1f6b32c01909c12d80fcdef
Reviewed-by: hjk <hjk@qt.io>