git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@40461 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2017-04-09 09:56:55 +00:00
parent 6df2b6f4c9
commit 073fb54804
3 changed files with 50 additions and 11 deletions

View file

@ -1,3 +1,10 @@
2017-04-09 Richard Frith-Macdonald <rfm@gnu.org>
* Headers/Foundation/NSTask.h:
* Source/NSTask.m:
Apply OSX compatibility fix for NSTask notifications (bug #49021)
by Larry Campbell.
2017-04-03 Richard Frith-Macdonald <rfm@gnu.org> 2017-04-03 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSOperation.m: Fix leak spotted by David Lobron. * Source/NSOperation.m: Fix leak spotted by David Lobron.

View file

@ -36,6 +36,8 @@
extern "C" { extern "C" {
#endif #endif
@class NSThread;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_5,GS_API_LATEST) #if OS_API_VERSION(MAC_OS_X_VERSION_10_5,GS_API_LATEST)
enum { enum {
NSTaskTerminationReasonExit = 1, NSTaskTerminationReasonExit = 1,
@ -61,6 +63,7 @@ typedef NSInteger NSTaskTerminationReason;
BOOL _hasTerminated; BOOL _hasTerminated;
BOOL _hasCollected; BOOL _hasCollected;
BOOL _hasNotified; BOOL _hasNotified;
NSThread *_launchingThread;
NSTaskTerminationReason _terminationReason; NSTaskTerminationReason _terminationReason;
#endif #endif
#if GS_NONFRAGILE #if GS_NONFRAGILE

View file

@ -222,6 +222,7 @@ pty_slave(const char* name)
@interface NSTask (Private) @interface NSTask (Private)
- (NSString *) _fullLaunchPath; - (NSString *) _fullLaunchPath;
- (void) _collectChild; - (void) _collectChild;
- (void) _notifyOfTermination;
- (void) _terminatedChild: (int)status reason: (NSTaskTerminationReason)reason; - (void) _terminatedChild: (int)status reason: (NSTaskTerminationReason)reason;
@end @end
@ -317,6 +318,7 @@ pty_slave(const char* name)
RELEASE(_standardError); RELEASE(_standardError);
RELEASE(_standardInput); RELEASE(_standardInput);
RELEASE(_standardOutput); RELEASE(_standardOutput);
RELEASE(_launchingThread);
[super dealloc]; [super dealloc];
} }
@ -407,10 +409,16 @@ pty_slave(const char* name)
* Raises an NSInvalidArgumentException if the launch path is not * Raises an NSInvalidArgumentException if the launch path is not
* set or if the subtask cannot be started for some reason * set or if the subtask cannot be started for some reason
* (eg. the executable does not exist or the task has already been launched). * (eg. the executable does not exist or the task has already been launched).
* The actual launching is done in a concrete subclass; this method just
* takes care of actions common to all subclasses.
*/ */
- (void) launch - (void) launch
{ {
[self subclassResponsibility: _cmd]; if (_launchingThread != [NSThread currentThread])
{
[_launchingThread release];
_launchingThread = [[NSThread currentThread] retain];
}
} }
/** /**
@ -900,6 +908,22 @@ pty_slave(const char* name)
[self subclassResponsibility: _cmd]; [self subclassResponsibility: _cmd];
} }
- (void) _notifyOfTermination
{
NSNotificationQueue *q;
NSNotification *n;
n = [NSNotification notificationWithName: NSTaskDidTerminateNotification
object: self
userInfo: nil];
q = [NSNotificationQueue defaultQueue];
[q enqueueNotification: n
postingStyle: NSPostASAP
coalesceMask: NSNotificationNoCoalescing
forModes: nil];
}
- (void) _terminatedChild: (int)status reason: (NSTaskTerminationReason)reason - (void) _terminatedChild: (int)status reason: (NSTaskTerminationReason)reason
{ {
[tasksLock lock]; [tasksLock lock];
@ -912,17 +936,18 @@ pty_slave(const char* name)
_hasTerminated = YES; _hasTerminated = YES;
if (_hasNotified == NO) if (_hasNotified == NO)
{ {
NSNotification *n;
_hasNotified = YES; _hasNotified = YES;
n = [NSNotification notificationWithName: NSTaskDidTerminateNotification if (_launchingThread != nil)
object: self {
userInfo: nil]; [self performSelector: @selector(_notifyOfTermination)
onThread: _launchingThread
[[NSNotificationQueue defaultQueue] enqueueNotification: n withObject: nil
postingStyle: NSPostASAP waitUntilDone: NO];
coalesceMask: NSNotificationNoCoalescing }
forModes: nil]; else
{
[self _notifyOfTermination];
}
} }
} }
@ -1128,6 +1153,8 @@ quotedFromString(NSString *aString)
format: @"NSTask - task has already been launched"]; format: @"NSTask - task has already been launched"];
} }
[super launch];
lpath = [self _fullLaunchPath]; lpath = [self _fullLaunchPath];
wexecutable = (const unichar*)[lpath fileSystemRepresentation]; wexecutable = (const unichar*)[lpath fileSystemRepresentation];
@ -1455,6 +1482,8 @@ GSPrivateCheckTasks()
format: @"NSTask - task has already been launched"]; format: @"NSTask - task has already been launched"];
} }
[super launch];
lpath = [self _fullLaunchPath]; lpath = [self _fullLaunchPath];
executable = [lpath fileSystemRepresentation]; executable = [lpath fileSystemRepresentation];
args[0] = executable; args[0] = executable;