Fix race condition in Unix wxExecute() if child exited too quickly.
Check if the child has already finished before starting waiting for it. Closes #16661.
This commit is contained in:
parent
1ad4596e8c
commit
1298f5970b
@ -67,6 +67,7 @@ All:
|
||||
|
||||
Unix:
|
||||
|
||||
- Fix bug in wxExecute() if child exited too quickly (Kevin B. McCarty).
|
||||
- Add --disable-sys-libs configure option.
|
||||
|
||||
All (GUI):
|
||||
|
@ -761,8 +761,6 @@ long wxExecute(char **argv, int flags, wxProcess *process,
|
||||
}
|
||||
else // we're in parent
|
||||
{
|
||||
execData.OnStart(pid);
|
||||
|
||||
// prepare for IO redirection
|
||||
|
||||
#if HAS_PIPE_STREAMS
|
||||
@ -814,17 +812,24 @@ long wxExecute(char **argv, int flags, wxProcess *process,
|
||||
pipeErr.Close();
|
||||
}
|
||||
|
||||
// For the asynchronous case we don't have to do anything else, just
|
||||
// let the process run.
|
||||
if ( !(flags & wxEXEC_SYNC) )
|
||||
{
|
||||
// Ensure that the housekeeping data is kept alive, it will be
|
||||
// destroyed only when the child terminates.
|
||||
execDataPtr.release();
|
||||
|
||||
return execData.pid;
|
||||
}
|
||||
|
||||
// Put the housekeeping data into the child process lookup table.
|
||||
// Note that when running asynchronously, if the child has already
|
||||
// finished this call will delete the execData and call any
|
||||
// wxProcess's OnTerminate() handler immediately.
|
||||
execData.OnStart(pid);
|
||||
|
||||
// For the asynchronous case we don't have to do anything else, just
|
||||
// let the process run (if not already finished).
|
||||
if ( !(flags & wxEXEC_SYNC) )
|
||||
return pid;
|
||||
|
||||
|
||||
// If we don't need to dispatch any events, things are relatively
|
||||
// simple and we don't need to delegate to wxAppTraits.
|
||||
@ -1608,9 +1613,21 @@ void wxExecuteData::OnStart(int pid_)
|
||||
if ( process )
|
||||
process->SetPid(pid);
|
||||
|
||||
// Finally, add this object itself to the list of child processes so that
|
||||
// Add this object itself to the list of child processes so that
|
||||
// we can check for its termination the next time we get SIGCHLD.
|
||||
ms_childProcesses[pid] = this;
|
||||
|
||||
// However, if the child exited before we finished setting up above,
|
||||
// we may have already missed its SIGCHLD. So we also do an explicit
|
||||
// check here before returning.
|
||||
int exitcode;
|
||||
if ( CheckForChildExit(pid, &exitcode) )
|
||||
{
|
||||
// Handle its termination if it did.
|
||||
// This call will implicitly remove it from ms_childProcesses
|
||||
// and, if running asynchronously, it will delete itself.
|
||||
OnExit(exitcode);
|
||||
}
|
||||
}
|
||||
|
||||
void wxExecuteData::OnExit(int exitcode_)
|
||||
|
Loading…
Reference in New Issue
Block a user