From ddbf0da92fabb3cce2d0b9ac437e4acd9c5cae05 Mon Sep 17 00:00:00 2001 From: CaS Date: Thu, 21 Jun 2001 04:49:20 +0000 Subject: [PATCH] Fixed task notification problem in nsrunloop git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@10219 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 7 +++ Source/NSRunLoop.m | 17 ++++++- Source/NSTask.m | 11 +++++ Testing/basic.m | 107 ++++++++++++++++++++++++++++++++++++--------- 4 files changed, 120 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index e5aecbda3..8d70f745b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2001-06-21 Richard Frith-Macdonald + + * Source/NSRunLoop.m: ([runMode:beforeDate:]) Check for task + completion and send out notifications if required. + * Source/NSTask.m: ([waitUntilExit]) schedule a timer so that the + run loop waits rather than polling as fast as the CPU allows. + 2001-06-20 Richard Frith-Macdonald * Source/NSTask.m: handleSignal() ... reset signal handler for diff --git a/Source/NSRunLoop.m b/Source/NSRunLoop.m index 692873d02..264bc1f8d 100644 --- a/Source/NSRunLoop.m +++ b/Source/NSRunLoop.m @@ -50,6 +50,7 @@ static int debug_run_loop = 0; static NSDate *theFuture = nil; +extern BOOL GSCheckTasks(); /* @@ -1016,7 +1017,6 @@ const NSMapTableValueCallBacks ArrayMapValueCallBacks = - (void) acceptInputForMode: (NSString*)mode beforeDate: limit_date { - extern BOOL GSCheckTasks(); NSTimeInterval ti; struct timeval timeout; void *select_timeout; @@ -1059,6 +1059,7 @@ const NSMapTableValueCallBacks ArrayMapValueCallBacks = { /* The LIMIT_DATE has already past; return immediately without polling any inputs. */ + GSCheckTasks(); [self _checkPerformers]; GSNotifyASAP(); if (debug_run_loop) @@ -1352,6 +1353,13 @@ const NSMapTableValueCallBacks ArrayMapValueCallBacks = { printf ("\tNSRunLoop run mode with date already past\n"); } + /* + * Notify if any tasks have completed. + */ + if (GSCheckTasks() == YES) + { + GSNotifyASAP(); + } return NO; } @@ -1363,6 +1371,13 @@ const NSMapTableValueCallBacks ArrayMapValueCallBacks = { printf ("\tNSRunLoop run mode with nothing to do\n"); } + /* + * Notify if any tasks have completed. + */ + if (GSCheckTasks() == YES) + { + GSNotifyASAP(); + } return NO; } diff --git a/Source/NSTask.m b/Source/NSTask.m index aae702551..1419421f3 100644 --- a/Source/NSTask.m +++ b/Source/NSTask.m @@ -515,6 +515,8 @@ pty_slave(const char* name) - (void) waitUntilExit { + NSTimer *timer = nil; + while ([self isRunning]) { NSDate *limit; @@ -523,10 +525,19 @@ pty_slave(const char* name) * Poll at 0.1 second intervals. */ limit = [[NSDate alloc] initWithTimeIntervalSinceNow: 0.1]; + if (timer = nil) + { + timer = [NSTimer scheduledTimerWithTimeInterval: 0.1 + target: nil + selector: @selector(class) + userInfo: nil + repeats: YES]; + } [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: limit]; RELEASE(limit); } + [timer invalidate]; } @end diff --git a/Testing/basic.m b/Testing/basic.m index d0674252a..7091d6e20 100644 --- a/Testing/basic.m +++ b/Testing/basic.m @@ -1,27 +1,92 @@ -#include -#include +#import -#if 1 -int main () +@interface TaskMan : NSObject { - id pool = [NSAutoreleasePool new]; - id o = [NSObject new]; - printf ("Hello from object at 0x%x\n", (unsigned)[o self]); - exit (0); + NSMutableArray *taskList; } -#else -int main (int argc, char **argv) + +-nextTask:(NSNotification *) aNotification; +@end + +@implementation TaskMan +-init { - NSString *string; - id pool = [NSAutoreleasePool new]; - NSProcessInfo *info = [NSProcessInfo processInfo]; - NSUserDefaults *defaults; - - NSLog(@"Temporary directory - %@", NSTemporaryDirectory()); - [info setProcessName: @"TestProcess"]; - defaults = [NSUserDefaults standardUserDefaults]; - NSLog(@"%@", [defaults dictionaryRepresentation]); - return 0; + NSTask *aTask; + + self = [super init]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(nextTask:) + name:NSTaskDidTerminateNotification + object:nil]; + + taskList = [[NSMutableArray alloc] init]; + + aTask = [[NSTask alloc] init]; + [aTask setLaunchPath:@"/bin/ls"]; + [aTask setArguments:nil]; + [taskList addObject:aTask]; + + aTask = [[NSTask alloc] init]; + [aTask setLaunchPath:@"/bin/ps"]; + [aTask setArguments:nil]; + [taskList addObject:aTask]; + + aTask = [[NSTask alloc] init]; + [aTask setLaunchPath:@"/bin/pwd"]; + [aTask setArguments:nil]; + [taskList addObject:aTask]; + + aTask = [[NSTask alloc] init]; + [aTask setLaunchPath:@"/bin/date"]; + [aTask setArguments:nil]; + [taskList addObject:aTask]; + + [[taskList objectAtIndex:0] launch]; + + return self; } -#endif + +-nextTask:(NSNotification *) aNotification +{ + if ([[aNotification object] terminationStatus] == 0) { + [NSNotification notificationWithName:@"CommandCompletedSuccessfully" + object:self]; + } else { + [NSNotification notificationWithName:@"CommandFailed" + object:self]; + } + [taskList removeObjectAtIndex:0]; + + if ([taskList count] > 0) + [[taskList objectAtIndex:0] launch]; + else + exit(0); + + return self; +} +@end + +int main(int argc, char **argv, char** env) +{ + NSAutoreleasePool *pool; + TaskMan *aTaskMan; + int i = 0; + + pool = [NSAutoreleasePool new]; + aTaskMan = [[TaskMan alloc] init]; + + while(1) { + [[NSRunLoop currentRunLoop] runOnceBeforeDate: + [NSDate dateWithTimeIntervalSinceNow: 5]]; + +/* Uncomment the following line, and the app will complete all tasks */ +/* otherwise it will hang */ +//printf("%d\n", i++); +// NSLog(@""); + } + + exit(0); +} +