Index: src/OFRunLoop.h ================================================================== --- src/OFRunLoop.h +++ src/OFRunLoop.h @@ -15,18 +15,20 @@ */ #import "OFObject.h" @class OFSortedList; +@class OFStreamObserver; @class OFTimer; /** * \brief A class providing a run loop for the application and its processes. */ @interface OFRunLoop: OFObject { OFSortedList *timersQueue; + OFStreamObserver *streamObserver; } /** * \brief Returns the main run loop. * Index: src/OFRunLoop.m ================================================================== --- src/OFRunLoop.m +++ src/OFRunLoop.m @@ -19,10 +19,11 @@ #import "OFRunLoop.h" #import "OFThread.h" #import "OFSortedList.h" #import "OFTimer.h" #import "OFDate.h" +#import "OFStreamObserver.h" static OFTLSKey *currentRunLoopKey; static OFRunLoop *mainRunLoop; @implementation OFRunLoop @@ -54,10 +55,12 @@ @try { void *pool = objc_autoreleasePoolPush(); timersQueue = [[[OFThread currentThread] _timersQueue] retain]; + streamObserver = [[OFStreamObserver alloc] init]; + [OFThread setObject: self forTLSKey: currentRunLoopKey]; objc_autoreleasePoolPop(pool); } @catch (id e) { @@ -69,19 +72,21 @@ } - (void)dealloc { [timersQueue release]; + [streamObserver release]; [super dealloc]; } - (void)addTimer: (OFTimer*)timer { @synchronized (timersQueue) { [timersQueue addObject: timer]; } + [streamObserver cancel]; } - (void)run { for (;;) { @@ -109,33 +114,24 @@ [timer fire]; objc_autoreleasePoolPop(pool2); } - /* Sleep until we reach the next timer */ - if (iter != NULL) - [OFThread sleepUntilDate: - [iter->object fireDate]]; - else { + /* Watch for stream events till the next timer is due */ + if (iter != NULL) { + double timeout = [[iter->object fireDate] + timeIntervalSinceNow]; + [streamObserver observeWithTimeout: timeout]; + } else { /* - * FIXME: - * Theoretically, another thread could add - * something to the run loop. This means we - * would need a way to block the thread until - * another event is added. The most easy way to - * achieve that would be if a run loop also - * handles streams: An OFStreamObserver could - * be called instead of sleepUntilDate above - * and get a timeout. If no timers are left, - * it could be called without a timeout and - * would automatically stop blocking once a new - * stream is added. This could also be used to - * stop blocking once a new timer is added. + * No more timers: Just watch for streams until + * we get an event. If a timer is added by + * another thread, it cancels the observe. */ - [OFThread sleepForTimeInterval: 24 * 3600]; + [streamObserver observe]; } } objc_autoreleasePoolPop(pool); } } @end