@@ -18,11 +18,13 @@ #include #import "OFRunLoop.h" #import "OFDictionary.h" -#import "OFStreamObserver.h" +#ifdef OF_HAVE_SOCKETS +# import "OFStreamObserver.h" +#endif #ifdef OF_HAVE_THREADS # import "OFThread.h" # import "OFMutex.h" #endif #import "OFSortedList.h" @@ -32,10 +34,11 @@ #import "autorelease.h" #import "macros.h" static OFRunLoop *mainRunLoop = nil; +#ifdef OF_HAVE_SOCKETS @interface OFRunLoop_QueueItem: OFObject { @public id _target; SEL _selector; @@ -43,45 +46,45 @@ @end @interface OFRunLoop_ReadQueueItem: OFRunLoop_QueueItem { @public -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS of_stream_async_read_block_t _block; -#endif +# endif void *_buffer; size_t _length; } @end @interface OFRunLoop_ExactReadQueueItem: OFRunLoop_QueueItem { @public -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS of_stream_async_read_block_t _block; -#endif +# endif void *_buffer; size_t _exactLength, _readLength; } @end @interface OFRunLoop_ReadLineQueueItem: OFRunLoop_QueueItem { @public -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS of_stream_async_read_line_block_t _block; -#endif +# endif of_string_encoding_t _encoding; } @end @interface OFRunLoop_AcceptQueueItem: OFRunLoop_QueueItem { @public -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS of_tcpsocket_async_accept_block_t _block; -#endif +# endif } @end @implementation OFRunLoop_QueueItem - (void)dealloc @@ -91,52 +94,53 @@ [super dealloc]; } @end @implementation OFRunLoop_ReadQueueItem -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS +- (void)dealloc +{ + [_block release]; + + [super dealloc]; +} +# endif +@end + +@implementation OFRunLoop_ExactReadQueueItem +# ifdef OF_HAVE_BLOCKS - (void)dealloc { [_block release]; [super dealloc]; } -#endif +# endif @end -@implementation OFRunLoop_ExactReadQueueItem -#ifdef OF_HAVE_BLOCKS +@implementation OFRunLoop_ReadLineQueueItem +# ifdef OF_HAVE_BLOCKS - (void)dealloc { [_block release]; [super dealloc]; } -#endif +# endif @end -@implementation OFRunLoop_ReadLineQueueItem -#ifdef OF_HAVE_BLOCKS +@implementation OFRunLoop_AcceptQueueItem +# ifdef OF_HAVE_BLOCKS - (void)dealloc { [_block release]; [super dealloc]; } -#endif -@end - -@implementation OFRunLoop_AcceptQueueItem -#ifdef OF_HAVE_BLOCKS -- (void)dealloc -{ - [_block release]; - - [super dealloc]; -} -#endif -@end +# endif +@end +#endif @implementation OFRunLoop + (OFRunLoop*)mainRunLoop { return [[mainRunLoop retain] autorelease]; @@ -154,11 +158,12 @@ + (void)OF_setMainRunLoop: (OFRunLoop*)runLoop { mainRunLoop = [runLoop retain]; } -#define ADD(type, code) \ +#ifdef OF_HAVE_SOCKETS +# define ADD(type, code) \ void *pool = objc_autoreleasePoolPush(); \ OFRunLoop *runLoop = [self currentRunLoop]; \ OFList *queue = [runLoop->_readQueues objectForKey: stream]; \ type *queueItem; \ \ @@ -225,11 +230,11 @@ queueItem->_target = [target retain]; queueItem->_selector = selector; }) } -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS + (void)OF_addAsyncReadForStream: (OFStream*)stream buffer: (void*)buffer length: (size_t)length block: (of_stream_async_read_block_t)block { @@ -267,13 +272,12 @@ { ADD(OFRunLoop_AcceptQueueItem, { queueItem->_block = [block copy]; }) } -#endif - -#undef ADD +# endif +# undef ADD + (void)OF_cancelAsyncRequestsForStream: (OFStream*)stream { void *pool = objc_autoreleasePoolPush(); OFRunLoop *runLoop = [self currentRunLoop]; @@ -286,10 +290,11 @@ [runLoop->_readQueues removeObjectForKey: stream]; } objc_autoreleasePoolPop(pool); } +#endif - init { self = [super init]; @@ -297,14 +302,16 @@ _timersQueue = [[OFSortedList alloc] init]; #ifdef OF_HAVE_THREADS _timersQueueLock = [[OFMutex alloc] init]; #endif +#ifdef OF_HAVE_SOCKETS _streamObserver = [[OFStreamObserver alloc] init]; [_streamObserver setDelegate: self]; _readQueues = [[OFMutableDictionary alloc] init]; +#endif } @catch (id e) { [self release]; @throw e; } @@ -315,12 +322,14 @@ { [_timersQueue release]; #ifdef OF_HAVE_THREADS [_timersQueueLock release]; #endif +#ifdef OF_HAVE_SOCKETS [_streamObserver release]; [_readQueues release]; +#endif [super dealloc]; } - (void)addTimer: (OFTimer*)timer @@ -336,11 +345,17 @@ } #endif [timer OF_setInRunLoop: self]; +#ifdef OF_HAVE_SOCKETS [_streamObserver cancel]; +#endif + +#if defined(OF_HAVE_THREADS) && !defined(OF_HAVE_SOCKETS) + /* FIXME: No way to cancel waiting! What to do? */ +#endif } - (void)OF_removeTimer: (OFTimer*)timer { #ifdef OF_HAVE_THREADS @@ -361,10 +376,11 @@ [_timersQueueLock unlock]; } #endif } +#ifdef OF_HAVE_SOCKETS - (void)streamIsReadyForReading: (OFStream*)stream { OFList *queue = [_readQueues objectForKey: stream]; of_list_object_t *listObject; @@ -384,11 +400,11 @@ } @catch (OFException *e) { length = 0; exception = e; } -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS if (queueItem->_block != NULL) { if (!queueItem->_block(stream, queueItem->_buffer, length, exception)) { [queue removeListObject: listObject]; @@ -398,11 +414,11 @@ [_readQueues removeObjectForKey: stream]; } } } else { -#endif +# endif bool (*func)(id, SEL, OFStream*, void*, size_t, OFException*) = (bool(*)(id, SEL, OFStream*, void*, size_t, OFException*)) [queueItem->_target methodForSelector: queueItem->_selector]; @@ -416,13 +432,13 @@ removeStreamForReading: stream]; [_readQueues removeObjectForKey: stream]; } } -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS } -#endif +# endif } else if ([listObject->object isKindOfClass: [OFRunLoop_ExactReadQueueItem class]]) { OFRunLoop_ExactReadQueueItem *queueItem = listObject->object; size_t length; OFException *exception = nil; @@ -439,11 +455,11 @@ } queueItem->_readLength += length; if (queueItem->_readLength == queueItem->_exactLength || [stream isAtEndOfStream] || exception != nil) { -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS if (queueItem->_block != NULL) { if (queueItem->_block(stream, queueItem->_buffer, queueItem->_readLength, exception)) queueItem->_readLength = 0; @@ -457,11 +473,11 @@ [_readQueues removeObjectForKey: stream]; } } } else { -#endif +# endif bool (*func)(id, SEL, OFStream*, void*, size_t, OFException*) = (bool(*)(id, SEL, OFStream*, void*, size_t, OFException*)) [queueItem->_target methodForSelector: queueItem->_selector]; @@ -480,13 +496,13 @@ stream]; [_readQueues removeObjectForKey: stream]; } } -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS } -#endif +# endif } } else if ([listObject->object isKindOfClass: [OFRunLoop_ReadLineQueueItem class]]) { OFRunLoop_ReadLineQueueItem *queueItem = listObject->object; OFString *line; @@ -500,11 +516,11 @@ exception = e; } if (line != nil || [stream isAtEndOfStream] || exception != nil) { -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS if (queueItem->_block != NULL) { if (!queueItem->_block(stream, line, exception)) { [queue removeListObject: listObject]; @@ -515,11 +531,11 @@ [_readQueues removeObjectForKey: stream]; } } } else { -#endif +# endif bool (*func)(id, SEL, OFStream*, OFString*, OFException*) = (bool(*)(id, SEL, OFStream*, OFString*, OFException*)) [queueItem->_target methodForSelector: queueItem->_selector]; @@ -535,13 +551,13 @@ stream]; [_readQueues removeObjectForKey: stream]; } } -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS } -#endif +# endif } } else if ([listObject->object isKindOfClass: [OFRunLoop_AcceptQueueItem class]]) { OFRunLoop_AcceptQueueItem *queueItem = listObject->object; OFTCPSocket *newSocket; @@ -552,11 +568,11 @@ } @catch (OFException *e) { newSocket = nil; exception = e; } -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS if (queueItem->_block != NULL) { if (!queueItem->_block((OFTCPSocket*)stream, newSocket, exception)) { [queue removeListObject: listObject]; @@ -566,11 +582,11 @@ [_readQueues removeObjectForKey: stream]; } } } else { -#endif +# endif bool (*func)(id, SEL, OFTCPSocket*, OFTCPSocket*, OFException*) = (bool(*)(id, SEL, OFTCPSocket*, OFTCPSocket*, OFException*)) [queueItem->_target methodForSelector: @@ -585,16 +601,17 @@ removeStreamForReading: stream]; [_readQueues removeObjectForKey: stream]; } } -#ifdef OF_HAVE_BLOCKS +# ifdef OF_HAVE_BLOCKS } -#endif +# endif } else OF_ENSURE(0); } +#endif - (void)run { _running = true; @@ -654,18 +671,26 @@ /* Watch for stream events until the next timer is due */ if (nextTimer != nil) { double timeout = [nextTimer timeIntervalSinceNow]; if (timeout > 0) +#ifdef OF_HAVE_SOCKETS [_streamObserver observeWithTimeout: timeout]; +#else + [OFThread sleepForTimeInterval: timeout]; +#endif } else { /* * No more timers: Just watch for streams until we get * an event. If a timer is added by another thread, it * cancels the observe. */ +#ifdef OF_HAVE_SOCKETS [_streamObserver observe]; +#else + [OFThread sleepForTimeInterval: 86400]; +#endif } objc_autoreleasePoolPop(pool); } } @@ -674,8 +699,14 @@ { _running = false; #ifdef OF_HAVE_THREADS of_memory_write_barrier(); #endif +#ifdef OF_HAVE_SOCKETS [_streamObserver cancel]; +#endif + +#if defined(OF_HAVE_THREADS) && !defined(OF_HAVE_SOCKETS) + /* FIXME: No way to cancel waiting! What to do? */ +#endif } @end