#import "ThreadManager.h" #import "Util.h" #define LOW_THREAD_NAME @"Audio Thread" #define NORMAL_THREAD_NAME @"Background Thread" #define HIGH_THREAD_NAME @"Blocking Working Thread" @implementation RunningThreadRunLoopPair @synthesize runLoop, thread; +(RunningThreadRunLoopPair*) startNewWithThreadName:(NSString*)name { require(name != nil); RunningThreadRunLoopPair* instance = [RunningThreadRunLoopPair new]; instance->thread = [[NSThread alloc] initWithTarget:instance selector:@selector(runLoopUntilCancelled) object:nil]; [instance->thread setName:name]; [instance->thread start]; [Operation asyncRunAndWaitUntilDone:^{ instance->runLoop = NSRunLoop.currentRunLoop; } onThread:instance->thread]; return instance; } -(void) terminate { [thread cancel]; } -(void) runLoopUntilCancelled { NSThread* curThread = NSThread.currentThread; NSRunLoop* curRunLoop = NSRunLoop.currentRunLoop; while (!curThread.isCancelled) { [curRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:5]]; } } @end @implementation ThreadManager static ThreadManager* sharedThreadManagerInternal; +(ThreadManager*)sharedThreadManager { @synchronized(self) { if (sharedThreadManagerInternal == nil){ sharedThreadManagerInternal = [ThreadManager new]; sharedThreadManagerInternal->low = [RunningThreadRunLoopPair startNewWithThreadName:LOW_THREAD_NAME]; sharedThreadManagerInternal->normal = [RunningThreadRunLoopPair startNewWithThreadName:NORMAL_THREAD_NAME]; sharedThreadManagerInternal->high = [RunningThreadRunLoopPair startNewWithThreadName:HIGH_THREAD_NAME]; } } return sharedThreadManagerInternal; } +(NSThread*)lowLatencyThread { return self.sharedThreadManager->low.thread; } +(NSRunLoop*)lowLatencyThreadRunLoop { return self.sharedThreadManager->low.runLoop; } +(NSThread*)normalLatencyThread { return self.sharedThreadManager->normal.thread; } +(NSRunLoop *)normalLatencyThreadRunLoop { return self.sharedThreadManager->normal.runLoop; } +(NSThread*)highLatencyThread { return self.sharedThreadManager->high.thread; } +(NSRunLoop *)highLatencyThreadRunLoop { return self.sharedThreadManager->high.runLoop; } +(void) terminate { @synchronized(self) { if (sharedThreadManagerInternal == nil) return; [sharedThreadManagerInternal->low terminate]; [sharedThreadManagerInternal->normal terminate]; [sharedThreadManagerInternal->high terminate]; sharedThreadManagerInternal = nil; } } @end