@@ -42,10 +42,11 @@ #import "OFDate.h" #import "OFObserveFailedException.h" #include "OFRunLoop_constants.m" + static OFRunLoop *mainRunLoop = nil; @interface OFRunLoopState: OFObject #ifdef OF_HAVE_SOCKETS @@ -74,16 +75,10 @@ # endif #endif } @end -OF_DIRECT_MEMBERS -@interface OFRunLoop () -- (OFRunLoopState *)of_stateForMode: (of_run_loop_mode_t)mode - create: (bool)create; -@end - #ifdef OF_HAVE_SOCKETS @interface OFRunLoopQueueItem: OFObject { @public id _delegate; @@ -94,11 +89,11 @@ @interface OFRunLoopReadQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS - of_stream_async_read_block_t _block; + OFStreamAsyncReadBlock _block; # endif void *_buffer; size_t _length; } @end @@ -105,11 +100,11 @@ @interface OFRunLoopExactReadQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS - of_stream_async_read_block_t _block; + OFStreamAsyncReadBlock _block; # endif void *_buffer; size_t _exactLength, _readLength; } @end @@ -116,21 +111,21 @@ @interface OFRunLoopReadLineQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS - of_stream_async_read_line_block_t _block; + OFStreamAsyncReadLineBlock _block; # endif - of_string_encoding_t _encoding; + OFStringEncoding _encoding; } @end @interface OFRunLoopWriteDataQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS - of_stream_async_write_data_block_t _block; + OFStreamAsyncWriteDataBlock _block; # endif OFData *_data; size_t _writtenLength; } @end @@ -137,14 +132,14 @@ @interface OFRunLoopWriteStringQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS - of_stream_async_write_string_block_t _block; + OFStreamAsyncWriteStringBlock _block; # endif OFString *_string; - of_string_encoding_t _encoding; + OFStringEncoding _encoding; size_t _writtenLength; } @end # if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) @@ -163,11 +158,11 @@ @interface OFRunLoopDatagramReceiveQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS - of_datagram_socket_async_receive_block_t _block; + OFDatagramSocketAsyncReceiveBlock _block; # endif void *_buffer; size_t _length; } @end @@ -174,22 +169,22 @@ @interface OFRunLoopDatagramSendQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS - of_datagram_socket_async_send_data_block_t _block; + OFDatagramSocketAsyncSendDataBlock _block; # endif OFData *_data; - of_socket_address_t _receiver; + OFSocketAddress _receiver; } @end @interface OFRunLoopPacketReceiveQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS - of_sequenced_packet_socket_async_receive_block_t _block; + OFSequencedPacketSocketAsyncReceiveBlock _block; # endif void *_buffer; size_t _length; } @end @@ -196,11 +191,11 @@ @interface OFRunLoopPacketSendQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS - of_sequenced_packet_socket_async_send_data_block_t _block; + OFSequencedPacketSocketAsyncSendDataBlock _block; # endif OFData *_data; } @end #endif @@ -280,27 +275,28 @@ assert(queue != nil); @try { if (![queue.firstObject handleObject: object]) { - of_list_object_t *listObject = queue.firstListObject; + OFListItem listItem = queue.firstListItem; /* * The handler might have called -[cancelAsyncRequests] * so that our queue is now empty, in which case we * should do nothing. */ - if (listObject != NULL) { + if (listItem != NULL) { /* * Make sure we keep the target until after we * are done removing the object. The reason for * this is that the target might call * -[cancelAsyncRequests] in its dealloc. */ - [[listObject->object retain] autorelease]; + [[OFListItemObject(listItem) retain] + autorelease]; - [queue removeListObject: listObject]; + [queue removeListItem: listItem]; if (queue.count == 0) { [_kernelEventObserver removeObjectForReading: object]; [_readQueues @@ -323,27 +319,28 @@ assert(queue != nil); @try { if (![queue.firstObject handleObject: object]) { - of_list_object_t *listObject = queue.firstListObject; + OFListItem listItem = queue.firstListItem; /* * The handler might have called -[cancelAsyncRequests] * so that our queue is now empty, in which case we * should do nothing. */ - if (listObject != NULL) { + if (listItem != NULL) { /* * Make sure we keep the target until after we * are done removing the object. The reason for * this is that the target might call * -[cancelAsyncRequests] in its dealloc. */ - [[listObject->object retain] autorelease]; + [[OFListItemObject(listItem) retain] + autorelease]; - [queue removeListObject: listObject]; + [queue removeListItem: listItem]; if (queue.count == 0) { [_kernelEventObserver removeObjectForWriting: object]; [_writeQueues @@ -427,12 +424,11 @@ { size_t length; id exception = nil; @try { - length = [object readIntoBuffer: _buffer - length: _length]; + length = [object readIntoBuffer: _buffer length: _length]; } @catch (id e) { length = 0; exception = e; } @@ -736,13 +732,11 @@ selector: @selector(of_socketDidConnect: exception:) object: object object: exception repeats: false]; - - [runLoop addTimer: timer - forMode: runLoop.currentMode]; + [runLoop addTimer: timer forMode: runLoop.currentMode]; } return false; } @end @@ -761,19 +755,18 @@ } # ifdef OF_HAVE_BLOCKS if (_block != NULL) { if ([object isKindOfClass: [OFStreamSocket class]]) - return ((of_stream_socket_async_accept_block_t) - _block)(acceptedSocket, exception); + return ((OFStreamSocketAsyncAcceptBlock)_block)( + acceptedSocket, exception); else if ([object isKindOfClass: [OFSequencedPacketSocket class]]) - return - ((of_sequenced_packet_socket_async_accept_block_t) + return ((OFSequencedPacketSocketAsyncAcceptBlock) _block)(acceptedSocket, exception); else - OF_ENSURE(0); + OFEnsure(0); } else { # endif if (![_delegate respondsToSelector: @selector(socket:didAcceptSocket:exception:)]) return false; @@ -798,11 +791,11 @@ @implementation OFRunLoopDatagramReceiveQueueItem - (bool)handleObject: (id)object { size_t length; - of_socket_address_t address; + OFSocketAddress address; id exception = nil; @try { length = [object receiveIntoBuffer: _buffer length: _length @@ -907,12 +900,11 @@ { size_t length; id exception = nil; @try { - length = [object receiveIntoBuffer: _buffer - length: _length]; + length = [object receiveIntoBuffer: _buffer length: _length]; } @catch (id e) { length = 0; exception = e; } @@ -1023,24 +1015,50 @@ + (void)of_setMainRunLoop: (OFRunLoop *)runLoop { mainRunLoop = [runLoop retain]; } + +static OFRunLoopState * +stateForMode(OFRunLoop *self, OFRunLoopMode mode, bool create) +{ + OFRunLoopState *state; + +#ifdef OF_HAVE_THREADS + [self->_statesMutex lock]; + @try { +#endif + state = [self->_states objectForKey: mode]; + + if (create && state == nil) { + state = [[OFRunLoopState alloc] init]; + @try { + [self->_states setObject: state forKey: mode]; + } @finally { + [state release]; + } + } +#ifdef OF_HAVE_THREADS + } @finally { + [self->_statesMutex unlock]; + } +#endif + + return state; +} #ifdef OF_HAVE_SOCKETS # define NEW_READ(type, object, mode) \ void *pool = objc_autoreleasePoolPush(); \ OFRunLoop *runLoop = [self currentRunLoop]; \ - OFRunLoopState *state = [runLoop of_stateForMode: mode \ - create: true]; \ + OFRunLoopState *state = stateForMode(runLoop, mode, true); \ OFList *queue = [state->_readQueues objectForKey: object]; \ type *queueItem; \ \ if (queue == nil) { \ queue = [OFList list]; \ - [state->_readQueues setObject: queue \ - forKey: object]; \ + [state->_readQueues setObject: queue forKey: object]; \ } \ \ if (queue.count == 0) \ [state->_kernelEventObserver \ addObjectForReading: object]; \ @@ -1047,19 +1065,17 @@ \ queueItem = [[[type alloc] init] autorelease]; # define NEW_WRITE(type, object, mode) \ void *pool = objc_autoreleasePoolPush(); \ OFRunLoop *runLoop = [self currentRunLoop]; \ - OFRunLoopState *state = [runLoop of_stateForMode: mode \ - create: true]; \ + OFRunLoopState *state = stateForMode(runLoop, mode, true); \ OFList *queue = [state->_writeQueues objectForKey: object]; \ type *queueItem; \ \ if (queue == nil) { \ queue = [OFList list]; \ - [state->_writeQueues setObject: queue \ - forKey: object]; \ + [state->_writeQueues setObject: queue forKey: object]; \ } \ \ if (queue.count == 0) \ [state->_kernelEventObserver \ addObjectForWriting: object]; \ @@ -1072,13 +1088,13 @@ + (void)of_addAsyncReadForStream: (OFStream *) stream buffer: (void *)buffer length: (size_t)length - mode: (of_run_loop_mode_t)mode + mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS - block: (of_stream_async_read_block_t)block + block: (OFStreamAsyncReadBlock)block # endif delegate: (id )delegate { NEW_READ(OFRunLoopReadQueueItem, stream, mode) @@ -1094,13 +1110,13 @@ + (void)of_addAsyncReadForStream: (OFStream *) stream buffer: (void *)buffer exactLength: (size_t)exactLength - mode: (of_run_loop_mode_t)mode + mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS - block: (of_stream_async_read_block_t)block + block: (OFStreamAsyncReadBlock)block # endif delegate: (id )delegate { NEW_READ(OFRunLoopExactReadQueueItem, stream, mode) @@ -1114,14 +1130,14 @@ QUEUE_ITEM } + (void)of_addAsyncReadLineForStream: (OFStream *) stream - encoding: (of_string_encoding_t)encoding - mode: (of_run_loop_mode_t)mode + encoding: (OFStringEncoding)encoding + mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS - block: (of_stream_async_read_line_block_t)block + block: (OFStreamAsyncReadLineBlock)block # endif delegate: (id )delegate { NEW_READ(OFRunLoopReadLineQueueItem, stream, mode) @@ -1135,13 +1151,13 @@ } + (void)of_addAsyncWriteForStream: (OFStream *) stream data: (OFData *)data - mode: (of_run_loop_mode_t)mode + mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS - block: (of_stream_async_write_data_block_t)block + block: (OFStreamAsyncWriteDataBlock)block # endif delegate: (id )delegate { NEW_WRITE(OFRunLoopWriteDataQueueItem, stream, mode) @@ -1155,14 +1171,14 @@ } + (void)of_addAsyncWriteForStream: (OFStream *) stream string: (OFString *)string - encoding: (of_string_encoding_t)encoding - mode: (of_run_loop_mode_t)mode + encoding: (OFStringEncoding)encoding + mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS - block: (of_stream_async_write_string_block_t)block + block: (OFStreamAsyncWriteStringBlock)block # endif delegate: (id )delegate { NEW_WRITE(OFRunLoopWriteStringQueueItem, stream, mode) @@ -1176,11 +1192,11 @@ QUEUE_ITEM } # if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) + (void)of_addAsyncConnectForSocket: (id)sock - mode: (of_run_loop_mode_t)mode + mode: (OFRunLoopMode)mode delegate: (id )delegate { NEW_WRITE(OFRunLoopConnectQueueItem, sock, mode) queueItem->_delegate = [delegate retain]; @@ -1188,11 +1204,11 @@ QUEUE_ITEM } # endif + (void)of_addAsyncAcceptForSocket: (id)sock - mode: (of_run_loop_mode_t)mode + mode: (OFRunLoopMode)mode block: (id)block delegate: (id)delegate { NEW_READ(OFRunLoopAcceptQueueItem, sock, mode) @@ -1205,13 +1221,13 @@ } + (void)of_addAsyncReceiveForDatagramSocket: (OFDatagramSocket *)sock buffer: (void *)buffer length: (size_t)length - mode: (of_run_loop_mode_t)mode + mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS - block: (of_datagram_socket_async_receive_block_t)block + block: (OFDatagramSocketAsyncReceiveBlock)block # endif delegate: (id )delegate { NEW_READ(OFRunLoopDatagramReceiveQueueItem, sock, mode) @@ -1225,14 +1241,14 @@ QUEUE_ITEM } + (void)of_addAsyncSendForDatagramSocket: (OFDatagramSocket *)sock data: (OFData *)data - receiver: (const of_socket_address_t *)receiver - mode: (of_run_loop_mode_t)mode + receiver: (const OFSocketAddress *)receiver + mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS - block: (of_datagram_socket_async_send_data_block_t)block + block: (OFDatagramSocketAsyncSendDataBlock)block # endif delegate: (id )delegate { NEW_WRITE(OFRunLoopDatagramSendQueueItem, sock, mode) @@ -1248,13 +1264,13 @@ + (void)of_addAsyncReceiveForSequencedPacketSocket: (OFSequencedPacketSocket *) sock buffer: (void *)buffer length: (size_t)length - mode: (of_run_loop_mode_t)mode + mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS - block: (of_sequenced_packet_socket_async_receive_block_t)block + block: (OFSequencedPacketSocketAsyncReceiveBlock)block # endif delegate: (id )delegate { NEW_READ(OFRunLoopPacketReceiveQueueItem, sock, mode) @@ -1268,13 +1284,13 @@ QUEUE_ITEM } + (void)of_addAsyncSendForSequencedPacketSocket: (OFSequencedPacketSocket *)sock data: (OFData *)data - mode: (of_run_loop_mode_t)mode + mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS - block: (of_sequenced_packet_socket_async_send_data_block_t)block + block: (OFSequencedPacketSocketAsyncSendDataBlock)block # endif delegate: (id )delegate { NEW_WRITE(OFRunLoopPacketSendQueueItem, sock, mode) @@ -1288,17 +1304,15 @@ } # undef NEW_READ # undef NEW_WRITE # undef QUEUE_ITEM -+ (void)of_cancelAsyncRequestsForObject: (id)object - mode: (of_run_loop_mode_t)mode ++ (void)of_cancelAsyncRequestsForObject: (id)object mode: (OFRunLoopMode)mode { void *pool = objc_autoreleasePoolPush(); OFRunLoop *runLoop = [self currentRunLoop]; - OFRunLoopState *state = [runLoop of_stateForMode: mode - create: false]; + OFRunLoopState *state = stateForMode(runLoop, mode, false); OFList *queue; if (state == nil) return; @@ -1341,12 +1355,11 @@ _states = [[OFMutableDictionary alloc] init]; state = [[OFRunLoopState alloc] init]; @try { - [_states setObject: state - forKey: of_run_loop_mode_default]; + [_states setObject: state forKey: OFDefaultRunLoopMode]; } @finally { [state release]; } #ifdef OF_HAVE_THREADS @@ -1368,50 +1381,18 @@ #endif [super dealloc]; } -- (OFRunLoopState *)of_stateForMode: (of_run_loop_mode_t)mode - create: (bool)create -{ - OFRunLoopState *state; - -#ifdef OF_HAVE_THREADS - [_statesMutex lock]; - @try { -#endif - state = [_states objectForKey: mode]; - - if (create && state == nil) { - state = [[OFRunLoopState alloc] init]; - @try { - [_states setObject: state - forKey: mode]; - } @finally { - [state release]; - } - } -#ifdef OF_HAVE_THREADS - } @finally { - [_statesMutex unlock]; - } -#endif - - return state; -} - -- (void)addTimer: (OFTimer *)timer -{ - [self addTimer: timer - forMode: of_run_loop_mode_default]; -} - -- (void)addTimer: (OFTimer *)timer - forMode: (of_run_loop_mode_t)mode -{ - OFRunLoopState *state = [self of_stateForMode: mode - create: true]; +- (void)addTimer: (OFTimer *)timer +{ + [self addTimer: timer forMode: OFDefaultRunLoopMode]; +} + +- (void)addTimer: (OFTimer *)timer forMode: (OFRunLoopMode)mode +{ + OFRunLoopState *state = stateForMode(self, mode, true); #ifdef OF_HAVE_THREADS [state->_timersQueueMutex lock]; @try { #endif @@ -1420,39 +1401,34 @@ } @finally { [state->_timersQueueMutex unlock]; } #endif - [timer of_setInRunLoop: self - mode: mode]; + [timer of_setInRunLoop: self mode: mode]; #if defined(OF_HAVE_SOCKETS) [state->_kernelEventObserver cancel]; #elif defined(OF_HAVE_THREADS) [state->_condition signal]; #endif } -- (void)of_removeTimer: (OFTimer *)timer - forMode: (of_run_loop_mode_t)mode +- (void)of_removeTimer: (OFTimer *)timer forMode: (OFRunLoopMode)mode { - OFRunLoopState *state = [self of_stateForMode: mode - create: false]; + OFRunLoopState *state = stateForMode(self, mode, false); if (state == nil) return; #ifdef OF_HAVE_THREADS [state->_timersQueueMutex lock]; @try { #endif - of_list_object_t *iter; - - for (iter = state->_timersQueue.firstListObject; iter != NULL; - iter = iter->next) { - if ([iter->object isEqual: timer]) { - [state->_timersQueue removeListObject: iter]; + for (OFListItem iter = state->_timersQueue.firstListItem; + iter != NULL; iter = OFListItemNext(iter)) { + if ([OFListItemObject(iter) isEqual: timer]) { + [state->_timersQueue removeListItem: iter]; break; } } #ifdef OF_HAVE_THREADS } @finally { @@ -1460,27 +1436,24 @@ } #endif } #ifdef OF_AMIGAOS -- (void)addExecSignal: (ULONG)signal - target: (id)target - selector: (SEL)selector +- (void)addExecSignal: (ULONG)signal target: (id)target selector: (SEL)selector { [self addExecSignal: signal - forMode: of_run_loop_mode_default + forMode: OFDefaultRunLoopMode target: target selector: selector]; } - (void)addExecSignal: (ULONG)signal - forMode: (of_run_loop_mode_t)mode + forMode: (OFRunLoopMode)mode target: (id)target selector: (SEL)selector { - OFRunLoopState *state = [self of_stateForMode: mode - create: true]; + OFRunLoopState *state = stateForMode(self, mode, true); # ifdef OF_HAVE_THREADS [state->_execSignalsMutex lock]; @try { # endif @@ -1509,22 +1482,21 @@ - (void)removeExecSignal: (ULONG)signal target: (id)target selector: (SEL)selector { [self removeExecSignal: signal - forMode: of_run_loop_mode_default + forMode: OFDefaultRunLoopMode target: target selector: selector]; } - (void)removeExecSignal: (ULONG)signal - forMode: (of_run_loop_mode_t)mode + forMode: (OFRunLoopMode)mode target: (id)target selector: (SEL)selector { - OFRunLoopState *state = [self of_stateForMode: mode - create: false]; + OFRunLoopState *state = stateForMode(self, mode, false); if (state == nil) return; # ifdef OF_HAVE_THREADS @@ -1580,21 +1552,18 @@ { _stop = false; while (!_stop && (deadline == nil || deadline.timeIntervalSinceNow >= 0)) - [self runMode: of_run_loop_mode_default - beforeDate: deadline]; + [self runMode: OFDefaultRunLoopMode beforeDate: deadline]; } -- (void)runMode: (of_run_loop_mode_t)mode - beforeDate: (OFDate *)deadline +- (void)runMode: (OFRunLoopMode)mode beforeDate: (OFDate *)deadline { void *pool = objc_autoreleasePoolPush(); - of_run_loop_mode_t previousMode = _currentMode; - OFRunLoopState *state = [self of_stateForMode: mode - create: false]; + OFRunLoopMode previousMode = _currentMode; + OFRunLoopState *state = stateForMode(self, mode, false); if (state == nil) return; _currentMode = mode; @@ -1609,23 +1578,23 @@ #ifdef OF_HAVE_THREADS [state->_timersQueueMutex lock]; @try { #endif - of_list_object_t *listObject = - state->_timersQueue.firstListObject; + OFListItem listItem = + state->_timersQueue.firstListItem; - if (listObject != NULL && [listObject->object - fireDate].timeIntervalSinceNow <= 0) { - timer = [[listObject->object + if (listItem != NULL && + [OFListItemObject(listItem) fireDate] + .timeIntervalSinceNow <= 0) { + timer = [[OFListItemObject(listItem) retain] autorelease]; [state->_timersQueue - removeListObject: listObject]; + removeListItem: listItem]; - [timer of_setInRunLoop: nil - mode: nil]; + [timer of_setInRunLoop: nil mode: nil]; } else break; #ifdef OF_HAVE_THREADS } @finally { [state->_timersQueueMutex unlock]; @@ -1650,11 +1619,11 @@ } #endif /* Watch for I/O events until the next timer is due */ if (nextTimer != nil || deadline != nil) { - of_time_interval_t timeout; + OFTimeInterval timeout; if (nextTimer != nil && deadline == nil) timeout = nextTimer.timeIntervalSinceNow; else if (nextTimer == nil && deadline != nil) timeout = deadline.timeIntervalSinceNow; @@ -1724,12 +1693,11 @@ } } - (void)stop { - OFRunLoopState *state = [self of_stateForMode: of_run_loop_mode_default - create: false]; + OFRunLoopState *state = stateForMode(self, OFDefaultRunLoopMode, false); _stop = true; if (state == nil) return;