Fix race condition on task termination

This commit is contained in:
rfm 2025-03-06 12:12:23 +00:00
parent 6307e474dd
commit 46c5917d5f
2 changed files with 38 additions and 18 deletions

View file

@ -1,6 +1,11 @@
2025-03-06 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSTask.m: bugfix for testing a running task ... the task may
still be running after a -terminate has been sent to it, until we have
been able to check for the termination status of the actual subprocess.
2025-02-28 Richard Frith-Macdonald <rfm@gnu.org>
* ChangeLog:
* Version:
* ANNOUNCE:
* NEWS:

View file

@ -397,11 +397,8 @@ pty_slave(const char* name)
{
return NO;
}
if (_hasCollected == NO)
{
[self _collectChild];
}
if (_hasTerminated == YES)
[self _collectChild];
if (_hasCollected)
{
return NO;
}
@ -465,6 +462,23 @@ pty_slave(const char* name)
return YES;
}
/**
* Checks to see if the task is currently running.
*/
- (BOOL) running
{
if (_hasLaunched == NO)
{
return NO;
}
[self _collectChild];
if (_hasCollected)
{
return NO;
}
return YES;
}
/**
* Sets an array of arguments to be supplied to the task when it
* is launched. The default is an empty array. This method cannot
@ -672,12 +686,16 @@ pty_slave(const char* name)
[NSException raise: NSInvalidArgumentException
format: @"NSTask - task has not yet launched"];
}
/* The _hasTerminated flag records whether this method has been called,
* not whether the task has *actually* terminated (_hasCollected does that).
*/
if (_hasTerminated)
{
return;
}
_hasTerminated = YES;
#ifndef _WIN32
#ifdef HAVE_KILLPG
killpg(_taskId, SIGTERM);
@ -699,11 +717,8 @@ pty_slave(const char* name)
[NSException raise: NSInvalidArgumentException
format: @"NSTask - task has not yet launched"];
}
[self _collectChild];
if (_hasCollected == NO)
{
[self _collectChild];
}
if (_hasTerminated == NO)
{
[NSException raise: NSInvalidArgumentException
format: @"NSTask - task has not yet terminated"];
@ -723,11 +738,8 @@ pty_slave(const char* name)
[NSException raise: NSInvalidArgumentException
format: @"NSTask - task has not yet launched"];
}
[self _collectChild];
if (_hasCollected == NO)
{
[self _collectChild];
}
if (_hasTerminated == NO)
{
[NSException raise: NSInvalidArgumentException
format: @"NSTask - task has not yet terminated"];
@ -1032,7 +1044,7 @@ pty_slave(const char* name)
_terminationStatus = status;
_terminationReason = reason;
_hasCollected = YES;
_hasTerminated = YES;
_hasTerminated = YES; // As if the -terminate method was called
if (_hasNotified == NO)
{
_hasNotified = YES;
@ -1119,15 +1131,18 @@ GSPrivateCheckTasks()
[NSException raise: NSInvalidArgumentException
format: @"NSTask - task has not yet launched"];
}
/* The _hasTerminated flag records whether this method has been called,
* not whether the task has *actually* terminated (_hasCollected does that).
*/
if (_hasTerminated)
{
return;
}
_hasTerminated = YES;
/* We use exit code 10 to denote a process termination.
* Windows does nt have an exit code to denote termination this way.
*/
_hasTerminated = YES;
TerminateProcess(procInfo.hProcess, WIN_SIGNALLED);
}