From 1e9cd3f6a7a0dba47f0abbca115c4394b43d73a4 Mon Sep 17 00:00:00 2001 From: Christopher Lloyd Date: Wed, 3 Mar 2010 16:59:02 +0000 Subject: [PATCH] issue #224 fix by Sven Weidauer --- Foundation/Foundation.h | 2 + .../Foundation.xcodeproj/project.pbxproj | 36 ++-- Foundation/NSOperation/NSOperation.h | 62 ++++-- Foundation/NSOperation/NSOperation.m | 188 +++++++++++++----- Foundation/NSOperation/NSOperationQueue.h | 27 ++- Foundation/NSOperation/NSOperationQueue.m | 61 +++++- 6 files changed, 279 insertions(+), 97 deletions(-) diff --git a/Foundation/Foundation.h b/Foundation/Foundation.h index 3a3fba26..db616821 100755 --- a/Foundation/Foundation.h +++ b/Foundation/Foundation.h @@ -102,6 +102,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #import #import #import +#import +#import #import #import #import diff --git a/Foundation/Foundation.xcodeproj/project.pbxproj b/Foundation/Foundation.xcodeproj/project.pbxproj index f3a188f1..01c73e68 100644 --- a/Foundation/Foundation.xcodeproj/project.pbxproj +++ b/Foundation/Foundation.xcodeproj/project.pbxproj @@ -324,8 +324,8 @@ 15D9203C105E918000171406 /* bonjour.h in Headers */ = {isa = PBXBuildFile; fileRef = FEE7D33B0ED1D4E10032DCE0 /* bonjour.h */; }; 15D9203D105E918000171406 /* NSAtomicList.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365D80F154B3A000F2657 /* NSAtomicList.h */; }; 15D9203E105E918000171406 /* NSLatchTrigger.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DA0F154B3A000F2657 /* NSLatchTrigger.h */; }; - 15D9203F105E918000171406 /* NSOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DC0F154B3A000F2657 /* NSOperation.h */; }; - 15D92040105E918000171406 /* NSOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DE0F154B3A000F2657 /* NSOperationQueue.h */; }; + 15D9203F105E918000171406 /* NSOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DC0F154B3A000F2657 /* NSOperation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 15D92040105E918000171406 /* NSOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DE0F154B3A000F2657 /* NSOperationQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; 15D92041105E918000171406 /* NSCancelInputSource_posix.h in Headers */ = {isa = PBXBuildFile; fileRef = C89B473D0F5C6AB50070120D /* NSCancelInputSource_posix.h */; }; 15D92042105E918000171406 /* NSRunLoopState_posix.h in Headers */ = {isa = PBXBuildFile; fileRef = FEA9D3090F5D9C5A00772064 /* NSRunLoopState_posix.h */; }; 15D92043105E918000171406 /* FoundationErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = FEC1CFDF0F7AAB7900619DD5 /* FoundationErrors.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1043,8 +1043,8 @@ 28D486370FE04E7100DC03EF /* bonjour.h in Headers */ = {isa = PBXBuildFile; fileRef = FEE7D33B0ED1D4E10032DCE0 /* bonjour.h */; }; 28D486380FE04E7100DC03EF /* NSAtomicList.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365D80F154B3A000F2657 /* NSAtomicList.h */; }; 28D486390FE04E7100DC03EF /* NSLatchTrigger.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DA0F154B3A000F2657 /* NSLatchTrigger.h */; }; - 28D4863A0FE04E7100DC03EF /* NSOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DC0F154B3A000F2657 /* NSOperation.h */; }; - 28D4863B0FE04E7100DC03EF /* NSOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DE0F154B3A000F2657 /* NSOperationQueue.h */; }; + 28D4863A0FE04E7100DC03EF /* NSOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DC0F154B3A000F2657 /* NSOperation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 28D4863B0FE04E7100DC03EF /* NSOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DE0F154B3A000F2657 /* NSOperationQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; 28D4863C0FE04E7100DC03EF /* NSCancelInputSource_posix.h in Headers */ = {isa = PBXBuildFile; fileRef = C89B473D0F5C6AB50070120D /* NSCancelInputSource_posix.h */; }; 28D4863D0FE04E7100DC03EF /* NSRunLoopState_posix.h in Headers */ = {isa = PBXBuildFile; fileRef = FEA9D3090F5D9C5A00772064 /* NSRunLoopState_posix.h */; }; 28D4863E0FE04E7100DC03EF /* FoundationErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = FEC1CFDF0F7AAB7900619DD5 /* FoundationErrors.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -2797,41 +2797,41 @@ FE1365E10F154B3A000F2657 /* NSAtomicList.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1365D90F154B3A000F2657 /* NSAtomicList.m */; }; FE1365E20F154B3A000F2657 /* NSLatchTrigger.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DA0F154B3A000F2657 /* NSLatchTrigger.h */; }; FE1365E30F154B3A000F2657 /* NSLatchTrigger.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1365DB0F154B3A000F2657 /* NSLatchTrigger.m */; }; - FE1365E40F154B3A000F2657 /* NSOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DC0F154B3A000F2657 /* NSOperation.h */; }; + FE1365E40F154B3A000F2657 /* NSOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DC0F154B3A000F2657 /* NSOperation.h */; settings = {ATTRIBUTES = (Public, ); }; }; FE1365E50F154B3A000F2657 /* NSOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1365DD0F154B3A000F2657 /* NSOperation.m */; }; - FE1365E60F154B3A000F2657 /* NSOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DE0F154B3A000F2657 /* NSOperationQueue.h */; }; + FE1365E60F154B3A000F2657 /* NSOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DE0F154B3A000F2657 /* NSOperationQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; FE1365E70F154B3A000F2657 /* NSOperationQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1365DF0F154B3A000F2657 /* NSOperationQueue.m */; }; FE1365E80F154B3A000F2657 /* NSAtomicList.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365D80F154B3A000F2657 /* NSAtomicList.h */; }; FE1365E90F154B3A000F2657 /* NSAtomicList.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1365D90F154B3A000F2657 /* NSAtomicList.m */; }; FE1365EA0F154B3A000F2657 /* NSLatchTrigger.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DA0F154B3A000F2657 /* NSLatchTrigger.h */; }; FE1365EB0F154B3A000F2657 /* NSLatchTrigger.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1365DB0F154B3A000F2657 /* NSLatchTrigger.m */; }; - FE1365EC0F154B3A000F2657 /* NSOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DC0F154B3A000F2657 /* NSOperation.h */; }; + FE1365EC0F154B3A000F2657 /* NSOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DC0F154B3A000F2657 /* NSOperation.h */; settings = {ATTRIBUTES = (Public, ); }; }; FE1365ED0F154B3A000F2657 /* NSOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1365DD0F154B3A000F2657 /* NSOperation.m */; }; - FE1365EE0F154B3A000F2657 /* NSOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DE0F154B3A000F2657 /* NSOperationQueue.h */; }; + FE1365EE0F154B3A000F2657 /* NSOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DE0F154B3A000F2657 /* NSOperationQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; FE1365EF0F154B3A000F2657 /* NSOperationQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1365DF0F154B3A000F2657 /* NSOperationQueue.m */; }; FE1365F00F154B3A000F2657 /* NSAtomicList.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365D80F154B3A000F2657 /* NSAtomicList.h */; }; FE1365F10F154B3A000F2657 /* NSAtomicList.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1365D90F154B3A000F2657 /* NSAtomicList.m */; }; FE1365F20F154B3A000F2657 /* NSLatchTrigger.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DA0F154B3A000F2657 /* NSLatchTrigger.h */; }; FE1365F30F154B3A000F2657 /* NSLatchTrigger.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1365DB0F154B3A000F2657 /* NSLatchTrigger.m */; }; - FE1365F40F154B3A000F2657 /* NSOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DC0F154B3A000F2657 /* NSOperation.h */; }; + FE1365F40F154B3A000F2657 /* NSOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DC0F154B3A000F2657 /* NSOperation.h */; settings = {ATTRIBUTES = (Public, ); }; }; FE1365F50F154B3A000F2657 /* NSOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1365DD0F154B3A000F2657 /* NSOperation.m */; }; - FE1365F60F154B3A000F2657 /* NSOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DE0F154B3A000F2657 /* NSOperationQueue.h */; }; + FE1365F60F154B3A000F2657 /* NSOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DE0F154B3A000F2657 /* NSOperationQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; FE1365F70F154B3A000F2657 /* NSOperationQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1365DF0F154B3A000F2657 /* NSOperationQueue.m */; }; FE1365F80F154B3A000F2657 /* NSAtomicList.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365D80F154B3A000F2657 /* NSAtomicList.h */; }; FE1365F90F154B3A000F2657 /* NSAtomicList.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1365D90F154B3A000F2657 /* NSAtomicList.m */; }; FE1365FA0F154B3A000F2657 /* NSLatchTrigger.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DA0F154B3A000F2657 /* NSLatchTrigger.h */; }; FE1365FB0F154B3A000F2657 /* NSLatchTrigger.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1365DB0F154B3A000F2657 /* NSLatchTrigger.m */; }; - FE1365FC0F154B3A000F2657 /* NSOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DC0F154B3A000F2657 /* NSOperation.h */; }; + FE1365FC0F154B3A000F2657 /* NSOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DC0F154B3A000F2657 /* NSOperation.h */; settings = {ATTRIBUTES = (Public, ); }; }; FE1365FD0F154B3A000F2657 /* NSOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1365DD0F154B3A000F2657 /* NSOperation.m */; }; - FE1365FE0F154B3A000F2657 /* NSOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DE0F154B3A000F2657 /* NSOperationQueue.h */; }; + FE1365FE0F154B3A000F2657 /* NSOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DE0F154B3A000F2657 /* NSOperationQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; FE1365FF0F154B3A000F2657 /* NSOperationQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1365DF0F154B3A000F2657 /* NSOperationQueue.m */; }; FE1366000F154B3A000F2657 /* NSAtomicList.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365D80F154B3A000F2657 /* NSAtomicList.h */; }; FE1366010F154B3A000F2657 /* NSAtomicList.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1365D90F154B3A000F2657 /* NSAtomicList.m */; }; FE1366020F154B3A000F2657 /* NSLatchTrigger.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DA0F154B3A000F2657 /* NSLatchTrigger.h */; }; FE1366030F154B3A000F2657 /* NSLatchTrigger.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1365DB0F154B3A000F2657 /* NSLatchTrigger.m */; }; - FE1366040F154B3A000F2657 /* NSOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DC0F154B3A000F2657 /* NSOperation.h */; }; + FE1366040F154B3A000F2657 /* NSOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DC0F154B3A000F2657 /* NSOperation.h */; settings = {ATTRIBUTES = (Public, ); }; }; FE1366050F154B3A000F2657 /* NSOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1365DD0F154B3A000F2657 /* NSOperation.m */; }; - FE1366060F154B3A000F2657 /* NSOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DE0F154B3A000F2657 /* NSOperationQueue.h */; }; + FE1366060F154B3A000F2657 /* NSOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DE0F154B3A000F2657 /* NSOperationQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; FE1366070F154B3A000F2657 /* NSOperationQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1365DF0F154B3A000F2657 /* NSOperationQueue.m */; }; FE1935170B5D449E00FB74CC /* NSAssertionHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1935150B5D449E00FB74CC /* NSAssertionHandler.h */; settings = {ATTRIBUTES = (Public, ); }; }; FE1935180B5D449E00FB74CC /* NSAssertionHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1935160B5D449E00FB74CC /* NSAssertionHandler.m */; }; @@ -3144,8 +3144,8 @@ FE30A17410C6ED6F00A1BF7F /* bonjour.h in Headers */ = {isa = PBXBuildFile; fileRef = FEE7D33B0ED1D4E10032DCE0 /* bonjour.h */; }; FE30A17510C6ED6F00A1BF7F /* NSAtomicList.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365D80F154B3A000F2657 /* NSAtomicList.h */; }; FE30A17610C6ED6F00A1BF7F /* NSLatchTrigger.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DA0F154B3A000F2657 /* NSLatchTrigger.h */; }; - FE30A17710C6ED6F00A1BF7F /* NSOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DC0F154B3A000F2657 /* NSOperation.h */; }; - FE30A17810C6ED6F00A1BF7F /* NSOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DE0F154B3A000F2657 /* NSOperationQueue.h */; }; + FE30A17710C6ED6F00A1BF7F /* NSOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DC0F154B3A000F2657 /* NSOperation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FE30A17810C6ED6F00A1BF7F /* NSOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DE0F154B3A000F2657 /* NSOperationQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; FE30A17910C6ED6F00A1BF7F /* NSCancelInputSource_posix.h in Headers */ = {isa = PBXBuildFile; fileRef = C89B473D0F5C6AB50070120D /* NSCancelInputSource_posix.h */; }; FE30A17A10C6ED6F00A1BF7F /* NSRunLoopState_posix.h in Headers */ = {isa = PBXBuildFile; fileRef = FEA9D3090F5D9C5A00772064 /* NSRunLoopState_posix.h */; }; FE30A17B10C6ED6F00A1BF7F /* FoundationErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = FEC1CFDF0F7AAB7900619DD5 /* FoundationErrors.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -4003,8 +4003,8 @@ FE65193A0FBC844C00464BFD /* NSDarwinString.h in Headers */ = {isa = PBXBuildFile; fileRef = C816EBED0F0A763500EDC3EB /* NSDarwinString.h */; settings = {ATTRIBUTES = (Private, ); }; }; FE65193B0FBC844C00464BFD /* NSAtomicList.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365D80F154B3A000F2657 /* NSAtomicList.h */; }; FE65193C0FBC844C00464BFD /* NSLatchTrigger.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DA0F154B3A000F2657 /* NSLatchTrigger.h */; }; - FE65193D0FBC844C00464BFD /* NSOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DC0F154B3A000F2657 /* NSOperation.h */; }; - FE65193E0FBC844C00464BFD /* NSOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DE0F154B3A000F2657 /* NSOperationQueue.h */; }; + FE65193D0FBC844C00464BFD /* NSOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DC0F154B3A000F2657 /* NSOperation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FE65193E0FBC844C00464BFD /* NSOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1365DE0F154B3A000F2657 /* NSOperationQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; FE65193F0FBC844C00464BFD /* NSCancelInputSource_posix.h in Headers */ = {isa = PBXBuildFile; fileRef = C89B473D0F5C6AB50070120D /* NSCancelInputSource_posix.h */; settings = {ATTRIBUTES = (Private, ); }; }; FE6519400FBC844C00464BFD /* NSRunLoopState_posix.h in Headers */ = {isa = PBXBuildFile; fileRef = FEA9D3090F5D9C5A00772064 /* NSRunLoopState_posix.h */; }; FE6519410FBC844C00464BFD /* FoundationErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = FEC1CFDF0F7AAB7900619DD5 /* FoundationErrors.h */; settings = {ATTRIBUTES = (Public, ); }; }; diff --git a/Foundation/NSOperation/NSOperation.h b/Foundation/NSOperation/NSOperation.h index e34081d9..99515e69 100644 --- a/Foundation/NSOperation/NSOperation.h +++ b/Foundation/NSOperation/NSOperation.h @@ -10,38 +10,64 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI */ #import +@class NSArray; +@class NSMutableArray; +enum { + NSOperationQueuePriorityVeryLow = -8, + NSOperationQueuePriorityLow = -4, + NSOperationQueuePriorityNormal = 0, + NSOperationQueuePriorityHigh = 4, + NSOperationQueuePriorityVeryHigh = 8 +}; +typedef NSInteger NSOperationQueuePriority; @interface NSOperation : NSObject { + NSOperationQueuePriority priority; + NSMutableArray *dependencies; + + int executing : 1; + int cancelled : 1; + int finished : 1; } +- (void)start; + // abstract, override this to create a concrete subclass, don't call super -- (void)run; +- (void)main; + +- (NSArray *)dependencies; +- (void)addDependency:(NSOperation *)operation; +- (void)removeDependency:(NSOperation *)operation; + +- (NSOperationQueuePriority)queuePriority; +- (void)setQueuePriority:(NSOperationQueuePriority)priority; + +- (BOOL)isCancelled; +- (void)cancel; + +- (BOOL)isConcurrent; +- (BOOL)isExecuting; +- (BOOL)isFinished; +- (BOOL)isReady; @end -@interface NSSelectorOperation : NSOperation +extern NSString * const NSInvocationOperationVoidResultException; +extern NSString * const NSInvocationOperationCancelledException; + + +@interface NSInvocationOperation : NSOperation { - id _obj; - SEL _sel; - id _arg; - - id _result; + NSInvocation *invocation; } -- (id)initWithTarget: (id)obj selector: (SEL)sel object: (id)arg; +- (id)initWithInvocation:(NSInvocation *)inv; +- (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg; + +- (NSInvocation *)invocation; - (id)result; @end - -@class NSLatchTrigger; -@interface NSWaitableSelectorOperation : NSSelectorOperation -{ - NSLatchTrigger* _trigger; -} - -- (void)waitUntilDone; - -@end diff --git a/Foundation/NSOperation/NSOperation.m b/Foundation/NSOperation/NSOperation.m index fd1b122c..f95c5b1e 100644 --- a/Foundation/NSOperation/NSOperation.m +++ b/Foundation/NSOperation/NSOperation.m @@ -11,94 +11,172 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI */ #import "NSOperation.h" -#import -#import #import "NSLatchTrigger.h" +#import +#import +#import +#import +#import +#import @implementation NSOperation -- (void)run + +- (void)main { NSLog( @"NSOperation is an abstract class, implement -[%@ %@]", [self class], NSStringFromSelector( _cmd ) ); [self doesNotRecognizeSelector: _cmd]; } -@end - -@implementation NSSelectorOperation - -- (id)initWithTarget: (id)obj selector: (SEL)sel object: (id)arg +- (NSArray *)dependencies; { - if( (self = [super init]) ) - { - _obj = [obj retain]; - _sel = sel; - _arg = [arg retain]; - } - return self; + return dependencies; } -- (void)dealloc +- (void)addDependency:(NSOperation *)operation; { - [_obj release]; - [_arg release]; - [_result release]; + if (nil == dependencies) { + dependencies = [[NSMutableArray alloc] init]; + } + [dependencies addObject: operation]; +} + +- (void)removeDependency:(NSOperation *)operation; +{ + if (nil != dependencies) { + [dependencies removeObject: operation]; + } +} + +- (NSOperationQueuePriority)queuePriority; +{ + return priority; +} + +- (void)setQueuePriority:(NSOperationQueuePriority)newPriority; +{ + priority = newPriority; +} + +- (BOOL)isCancelled; +{ + return cancelled; +} + +- (void)cancel; +{ + [self willChangeValueForKey: @"isCancelled"]; + cancelled = 1; + [self didChangeValueForKey: @"isCancelled"]; +} + +- (BOOL)isConcurrent; +{ + return NO; +} + +- (BOOL)isExecuting; +{ + return executing; +} + +- (BOOL)isFinished; +{ + return finished; +} + +- (BOOL)isReady; +{ + for (NSOperation *op in dependencies) { + if (![op isFinished]) return NO; + } + return YES; +} + +- (void) start; +{ + if (!executing && !finished) { + if (!cancelled) { + [self willChangeValueForKey: @"isExecuting"]; + executing = 1; + [self didChangeValueForKey: @"isExecuting"]; + + [self main]; + } + + [self willChangeValueForKey: @"isExecuting"]; + [self willChangeValueForKey: @"isFinished"]; + executing = 0; + finished = 1; + [self didChangeValueForKey: @"isFinished"]; + [self didChangeValueForKey: @"isExecuting"]; + } +} + +- (void) dealloc; +{ + [dependencies release], dependencies = 0; [super dealloc]; } -- (NSString *)description -{ - return [NSString stringWithFormat: @"<%@:%p: %@ %@ %@>", [self class], self, _obj, NSStringFromSelector( _sel ), _arg]; -} - -- (void)run -{ - NSMethodSignature *sig = [_obj methodSignatureForSelector: _sel]; - IMP imp=[_obj instanceMethodForSelector:_sel]; - - if( [sig methodReturnType][0] == '@' ) - _result = [imp( _obj, _sel, _arg ) retain]; - else - imp( _obj, _sel, _arg ); -} - -- (id)result -{ - return _result; -} - @end -@implementation NSWaitableSelectorOperation +NSString * const NSInvocationOperationVoidResultException = @"NSInvocationOperationVoidResultException"; +NSString * const NSInvocationOperationCancelledException = @"NSInvocationOperationCancelledException"; -- (id)initWithTarget: (id)obj selector: (SEL)sel object: (id)arg + +@implementation NSInvocationOperation + +- (id)initWithInvocation:(NSInvocation *)inv; { - if( (self = [super initWithTarget: obj selector: sel object: arg]) ) - { - _trigger = [[NSLatchTrigger alloc] init]; - } + if (nil == [super init]) return nil; + invocation = [inv retain]; return self; } +- (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg; +{ + NSMethodSignature *signature = [target methodSignatureForSelector: sel]; + NSInvocation *inv = [NSInvocation invocationWithMethodSignature: signature]; + [inv setTarget: target]; + [inv setSelector: sel]; + [inv setArgument: &arg atIndex:2]; + + return [self initWithInvocation: inv]; +} + +- (NSInvocation *)invocation; +{ + return invocation; +} + +- (id)result; +{ + if ([self isCancelled]) [NSException raise: NSInvocationOperationCancelledException format: @"" ]; + + id result = 0; + if ([[invocation methodSignature] methodReturnLength] != sizeof( result )) [NSException raise: NSInvocationOperationVoidResultException format: @""]; + + [invocation getReturnValue: &result]; + return result; +} + - (void)dealloc { - [_trigger release]; + [invocation release], invocation = nil; [super dealloc]; } -- (void)run +- (void) main; { - [super run]; - [_trigger signal]; -} - -- (void)waitUntilDone -{ - [_trigger wait]; + [invocation invoke]; } @end + + + diff --git a/Foundation/NSOperation/NSOperationQueue.h b/Foundation/NSOperation/NSOperationQueue.h index 7bede1f5..5bc419e2 100644 --- a/Foundation/NSOperation/NSOperationQueue.h +++ b/Foundation/NSOperation/NSOperationQueue.h @@ -14,15 +14,38 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI @class NSOperation; @class NSOperationQueueImpl; +@class NSArray; + +enum { + NSOperationQueueDefaultMaxConcurrentOperationCount = -1 +}; + @interface NSOperationQueue : NSObject { - NSOperationQueueImpl* _impl; + NSOperationQueueImpl *_impl; + NSString *_name; } - (id)init; - (void)addOperation: (NSOperation *)op; -- (void)addHighPriorityOperation: (NSOperation *)op; + +- (void)addOperations:(NSArray *)ops waitUntilFinished:(BOOL)wait; + +- (void)cancelAllOperations; + +- (NSInteger)maxConcurrentOperationCount; +- (void)setMaxConcurrentOperationCount:(NSInteger)count; + +- (NSString *)name; +- (void)setName:(NSString *)newName; + +- (NSArray *)operations; + +- (BOOL)isSuspended; +- (void)setSuspended:(BOOL)suspend; + +- (void)waitUntilAllOperationsAreFinished; @end diff --git a/Foundation/NSOperation/NSOperationQueue.m b/Foundation/NSOperation/NSOperationQueue.m index 74d5b05d..e4537316 100644 --- a/Foundation/NSOperation/NSOperationQueue.m +++ b/Foundation/NSOperation/NSOperationQueue.m @@ -17,6 +17,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #import "NSAtomicList.h" #import "NSLatchTrigger.h" +#import @interface NSOperationQueueImpl : NSObject @@ -109,7 +110,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI } if( op ) - [op run]; + [op start]; return op != nil; } @@ -178,12 +179,64 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI - (void)addOperation: (NSOperation *)op { - [_impl addOperation: op]; + if ([op queuePriority] > NSOperationQueuePriorityNormal) [_impl addHighPriorityOperation: op]; + else [_impl addOperation: op]; } -- (void)addHighPriorityOperation: (NSOperation *)op +- (void)addOperations:(NSArray *)ops waitUntilFinished:(BOOL)wait; { - [_impl addHighPriorityOperation: op]; + NSUnimplementedMethod(); +} + +- (void)cancelAllOperations; +{ + NSUnimplementedMethod(); +} + +- (NSInteger)maxConcurrentOperationCount; +{ + NSUnimplementedMethod(); + return NSOperationQueueDefaultMaxConcurrentOperationCount; +} + +- (void)setMaxConcurrentOperationCount:(NSInteger)count; +{ + NSUnimplementedMethod(); +} + +- (NSString *)name; +{ + return [[_name retain] autorelease]; +} + +- (void)setName:(NSString *)newName; +{ + if (_name != newName) { + [_name release]; + _name = [newName copy]; + } +} + +- (NSArray *)operations; +{ + NSUnimplementedMethod(); + return nil; +} + +- (BOOL)isSuspended; +{ + NSUnimplementedMethod(); + return NO; +} + +- (void)setSuspended:(BOOL)suspend; +{ + NSUnimplementedMethod(); +} + +- (void)waitUntilAllOperationsAreFinished; +{ + NSUnimplementedMethod(); } @end