35#define USE_PTHREAD_ONCE (!OOLITE_WINDOWS) 
   45@interface NSThread (MethodsThatMayExistDependingOnSystem)
 
   65- (void) queueResult:(
id<OOAsyncWorkTask>)task;
 
   67- (void) noteTaskQueued:(
id<OOAsyncWorkTask>)task;
 
   72#if !OO_HAVE_NSOPERATION 
   79- (void) queueTask:(NSNumber *)threadNumber;
 
   91#if !OO_HAVE_NSOPERATION 
   95- (void) dispatchTask:(
id<OOAsyncWorkTask>)task;
 
  101static NSLock *sInitLock = 
nil;
 
  107    NSCAssert(
sSingleton == 
nil, 
@"Async Work Manager singleton not nil in one-time init");
 
  109#if !OO_HAVE_NSOPERATION 
  116        sSingleton = [[OOManualDispatchAsyncWorkManager alloc] init];
 
  124        OOLog(
@"asyncWorkManager.setUpDispatcher.failed", 
@"%@", 
@"***** FATAL ERROR: could not set up async work manager!");
 
  128    OOLog(
@"asyncWorkManager.dispatchMethod", 
@"Selected async work manager: %@", [
sSingleton class]);
 
 
  132@implementation OOAsyncWorkManager
 
  137    if (sInitLock == 
nil)
 
  139        sInitLock = [[NSLock alloc] init];
 
  140        NSAssert(sInitLock != 
nil, 
@"Async Work Manager init failed");
 
  149    static pthread_once_t once = PTHREAD_ONCE_INIT;
 
  151    NSAssert(
sSingleton != 
nil, 
@"Async Work Manager init failed");
 
  157        NSAssert(
sSingleton != 
nil, 
@"Async Work Manager init failed");
 
 
  166+ (id) allocWithZone:(NSZone *)inZone
 
   166+ (id) allocWithZone:(NSZone *)inZone {
…}
  
  213- (void) waitForTaskToComplete:(
id<OOAsyncWorkTask>)task
 
  216    [
NSException raise:NSInternalInconsistencyException format:@"%s called.", __PRETTY_FUNCTION__];
 
   213- (void) waitForTaskToComplete:(
id<OOAsyncWorkTask>)task {
…}
  
  227    if ((
self = [super 
init]))
 
 
  255    [_pendingOpsLock lock];
 
  259        if (next == 
nil)  
break;
 
  261        [_pendingCompletableOperations removeObject:next];
 
  262        [
next completeAsyncTask];
 
  264    [_pendingOpsLock unlock];
 
 
  268- (void) waitForTaskToComplete:(
id<OOAsyncWorkTask>)task
 
  270    if (task == 
nil)  
return;
 
  273    NSParameterAssert([(
id)task respondsToSelector:
@selector(completeAsyncTask)]);
 
  274    NSAssert1(![NSThread respondsToSelector:
@selector(isMainThread)] || [[NSThread 
self] isMainThread], 
@"%s can only be called from the main thread.", __PRETTY_FUNCTION__);
 
  277    [_pendingOpsLock lock];
 
  278    BOOL exists = [_pendingCompletableOperations containsObject:task];
 
  279    if (exists)  [_pendingCompletableOperations removeObject:task];
 
  280    [_pendingOpsLock unlock];
 
  289        [_pendingOpsLock lock];
 
  290        [_pendingCompletableOperations removeObject:next];
 
  291        [_pendingOpsLock unlock];
 
  293        [
next completeAsyncTask];
 
  295    }  
while (next != task);    
 
   268- (void) waitForTaskToComplete:(
id<OOAsyncWorkTask>)task {
…}
  
  299- (void) queueResult:(
id<OOAsyncWorkTask>)task
 
  301    if ([task respondsToSelector:
@selector(completeAsyncTask)])
 
   299- (void) queueResult:(
id<OOAsyncWorkTask>)task {
…}
  
  308- (void) noteTaskQueued:(
id<OOAsyncWorkTask>)task
 
  310    [_pendingOpsLock lock];
 
  311    [_pendingCompletableOperations addObject:task];
 
  312    [_pendingOpsLock unlock];
 
   308- (void) noteTaskQueued:(
id<OOAsyncWorkTask>)task {
…}
  
  327#if !OO_HAVE_NSOPERATION 
  328@implementation OOManualDispatchAsyncWorkManager
 
  332    if ((
self = [super init]))
 
  336        if (_taskQueue == 
nil)
 
  343        NSUInteger threadCount, threadNumber = 1;
 
  351            [NSThread detachNewThreadSelector:@selector(queueTask:) toTarget:
self withObject:[NSNumber numberWithInt:threadNumber++]];
 
  352        }  
while (--threadCount > 0);
 
  363    [
super noteTaskQueued:task];
 
  366    return [_taskQueue enqueue:task];
 
  370- (void) queueTask:(NSNumber *)threadNumber
 
  372    NSAutoreleasePool           *rootPool = 
nil, *pool = 
nil;
 
  374    rootPool = [[NSAutoreleasePool alloc] init];
 
  376    [NSThread setThreadPriority:0.5];
 
  377    [NSThread ooSetCurrentThreadName:[NSString stringWithFormat:@"OOAsyncWorkManager thread %@", threadNumber]];
 
  381        pool = [[NSAutoreleasePool alloc] init];
 
  383        id<OOAsyncWorkTask> task = [_taskQueue dequeue];
 
  386            [task performAsyncTask];
 
  388        @catch (
id exception) {}
 
  389        [
self queueResult:task];
 
  404@implementation OOOperationQueueAsyncWorkManager
 
  406#if !OO_HAVE_NSOPERATION 
  409    if ([[NSUserDefaults standardUserDefaults] boolForKey:
@"disable-operation-queue-work-manager"])  
return NO;
 
  410    return [OONSInvocationOperationClass() class] != Nil;
 
  417    if ((
self = [super 
init]))
 
 
  434    [_operationQueue release];
 
 
  444    id operation = [[OONSInvocationOperationClass() alloc] initWithTarget:
self selector:@selector(dispatchTask:) object:task];
 
  445    if (operation == 
nil)  
return NO;
 
  450    [_operationQueue addOperation:operation];
 
 
  458- (void) dispatchTask:(
id<OOAsyncWorkTask>)task
 
  462        [
task performAsyncTask];
 
  464    @catch (
id exception) {}
 
   458- (void) dispatchTask:(
id<OOAsyncWorkTask>)task {
…}
  
static void InitAsyncWorkManager(void)
 
NSUInteger OOCPUCount(void)
 
static OODebugMonitor * sSingleton
 
#define OOLogGenericSubclassResponsibility()
 
#define OOLog(class, format,...)
 
#define OONSOperationQueue
 
OOAsyncQueue * _readyQueue
 
NSMutableSet * _pendingCompletableOperations
 
void completePendingTasks()
 
void noteTaskQueued:(id< OOAsyncWorkTask > task)
 
void queueResult:(id< OOAsyncWorkTask > task)
 
void completePendingTasks()
 
OOAsyncWorkManager * sharedAsyncWorkManager()
 
OONSOperationQueue _operationQueue