[Development] bool QProcess::waitForFinished() Race Condition?

d3fault d3faultdotxbe at gmail.com
Wed Sep 26 08:45:30 CEST 2012


Unable to confirm the race condition, which is why I'm posting here
instead of filing the bug report. Isn't there a race condition between
calling QProcess::start() and QProcess::waitForFinished()?

Can't the OS switch contexts at ANY TIME (in this case, between the
start() and waitForFinished() calls)?

Scenario:

QProcess proc;
proc.start("aVerySmallBinary");
//OS switches contexts by sheer chance right here to the newly started
process. If the process is short enough it could finish and exit
cleanly before executing the following line
bool finished = proc.waitForFinished();
//finished should be true, but in the race condition case it will be
false because waitForFinished "returns false ... if this QProcess is
already finished" (doc).

One way to safely start/finish a process without the race condition is
to use the static method QProcess::execute()..... but then you can't
capture stdout/stderr or listen for the QProcess::error() etc etc etc.
All you get with QProcess::execute() is the exit code as an integer
returned to you (output is simply forwarded to your process).

I tried testing/proving the race condition by doing a
QWaitCondition::wait() in between start() and waitForFinished() with a
3000 ms timeout (as way of sleeping)... but couldn't get it to
trigger. QProcess::waitForFinished() always returned true (my process
was "/bin/echo test"). I did however get waitForFinished to return
false when I called start() in one slot (attached to QPushButton I
press) and waitForFinished in another slot (from a different
QPushButton I press). I would be very much questioning my sanity if
waitForFinished() didn't return false in the second case... so it
doesn't really tell me anything. Maybe the code driving QProcess
already accounts for this race condition (something along the lines of
calling waitForFinished() within the same... errr... slot (event?) as
start() catches the rare case where the process finishes before you
call waitForFinished? Maybe I am simply testing it wrong and the race
condition exists? I do not know) and the documentation should be
updated accordingly so future users don't get confused as I am now?

Proposed Fix (if there is even a problem (if there isn't, the fix is
to update the docs)): Add a non-static method similar to execute()
that starts and waits for finish in one call. Perhaps called int
QProcess::startAndWaitForFinished(). This way we get the safety of
QProcess::execute() but without losing all the non-static
functionality that QProcess provides.

d3fault

p.s. maybe my fundamental understanding of how QProcess works is
wrong. Isn't the process run asynchronously? Or is that only with
startDetached()?? I am under the impression that startDetached() is
the same as start() in that they are both asynchronous... with the
difference being that a process started with startDetached continues
to run after the calling process (us) exits. Does start() run the
program synchronously? The more I think about it the more I doubt
that. How would I even be able to call waitForFinished() while it's
running if that was the case?



More information about the Development mailing list