Index: src/OFDNSResolver.m ================================================================== --- src/OFDNSResolver.m +++ src/OFDNSResolver.m @@ -618,22 +618,10 @@ [super dealloc]; } @end @implementation OFDNSResolver -#ifdef OF_AMIGAOS -+ (void)initialize -{ - if (self != [OFDNSResolver class]) - return; - - if (!_OFSocketInit()) - @throw [OFInitializationFailedException - exceptionWithClass: self]; -} -#endif - + (instancetype)resolver { return [[[self alloc] init] autorelease]; } @@ -640,10 +628,14 @@ - (instancetype)init { self = [super init]; @try { + if (!_OFSocketInit()) + @throw [OFInitializationFailedException + exceptionWithClass: self.class]; + _settings = [[OFDNSResolverSettings alloc] init]; _queries = [[OFMutableDictionary alloc] init]; _TCPQueries = [[OFMutableDictionary alloc] init]; _cache = [[OFMutableDictionary alloc] init]; Index: src/OFDatagramSocket.m ================================================================== --- src/OFDatagramSocket.m +++ src/OFDatagramSocket.m @@ -53,20 +53,10 @@ #endif @implementation OFDatagramSocket @synthesize delegate = _delegate; -+ (void)initialize -{ - if (self != [OFDatagramSocket class]) - return; - - if (!_OFSocketInit()) - @throw [OFInitializationFailedException - exceptionWithClass: self]; -} - + (instancetype)socket { return [[[self alloc] init] autorelease]; } @@ -78,10 +68,14 @@ if (self.class == [OFDatagramSocket class]) { [self doesNotRecognizeSelector: _cmd]; abort(); } + if (!_OFSocketInit()) + @throw [OFInitializationFailedException + exceptionWithClass: self.class]; + _socket = OFInvalidSocketHandle; #ifdef OF_HAVE_AMIGAOS _socketID = -1; #endif _canBlock = true; Index: src/OFKernelEventObserver.m ================================================================== --- src/OFKernelEventObserver.m +++ src/OFKernelEventObserver.m @@ -59,20 +59,10 @@ @synthesize delegate = _delegate; #ifdef OF_AMIGAOS @synthesize execSignalMask = _execSignalMask; #endif -+ (void)initialize -{ - if (self != [OFKernelEventObserver class]) - return; - - if (!_OFSocketInit()) - @throw [OFInitializationFailedException - exceptionWithClass: self]; -} - + (instancetype)observer { return [[[self alloc] init] autorelease]; } @@ -102,10 +92,14 @@ #if !defined(OF_HAVE_PIPE) && !defined(OF_WII) && !defined(OF_AMIGAOS) && \ !defined(OF_NINTENDO_3DS) socklen_t cancelAddrLen; #endif + if (!_OFSocketInit()) + @throw [OFInitializationFailedException + exceptionWithClass: self.class]; + _readObjects = [[OFMutableArray alloc] init]; _writeObjects = [[OFMutableArray alloc] init]; #if defined(OF_HAVE_PIPE) && !defined(OF_AMIGAOS) if (pipe(_cancelFD)) Index: src/OFRunLoop.m ================================================================== --- src/OFRunLoop.m +++ src/OFRunLoop.m @@ -59,14 +59,15 @@ @public OFSortedList OF_GENERIC(OFTimer *) *_timersQueue; #ifdef OF_HAVE_THREADS OFMutex *_timersQueueMutex; #endif -#if defined(OF_HAVE_SOCKETS) +#ifdef OF_HAVE_SOCKETS OFKernelEventObserver *_kernelEventObserver; OFMutableDictionary *_readQueues, *_writeQueues; -#elif defined(OF_HAVE_THREADS) +#endif +#ifdef OF_HAVE_THREADS OFCondition *_condition; # ifdef OF_AMIGAOS ULONG _execSignalMask; # endif #endif @@ -237,17 +238,15 @@ _timersQueue = [[OFSortedList alloc] init]; #ifdef OF_HAVE_THREADS _timersQueueMutex = [[OFMutex alloc] init]; #endif -#if defined(OF_HAVE_SOCKETS) - _kernelEventObserver = [[OFKernelEventObserver alloc] init]; - _kernelEventObserver.delegate = self; - +#ifdef OF_HAVE_SOCKETS _readQueues = [[OFMutableDictionary alloc] init]; _writeQueues = [[OFMutableDictionary alloc] init]; -#elif defined(OF_HAVE_THREADS) +#endif +#if defined(OF_HAVE_THREADS) _condition = [[OFCondition alloc] init]; #endif #ifdef OF_AMIGAOS _execSignals = [[OFMutableData alloc] initWithItemSize: sizeof(ULONG)]; @@ -270,15 +269,16 @@ { [_timersQueue release]; #ifdef OF_HAVE_THREADS [_timersQueueMutex release]; #endif -#if defined(OF_HAVE_SOCKETS) +#ifdef OF_HAVE_SOCKETS [_kernelEventObserver release]; [_readQueues release]; [_writeQueues release]; -#elif defined(OF_HAVE_THREADS) +#endif +#ifdef OF_HAVE_THREADS [_condition release]; #endif #ifdef OF_AMIGAOS [_execSignals release]; [_execSignalsTargets release]; @@ -1164,11 +1164,12 @@ { mainRunLoop = [runLoop retain]; } static OFRunLoopState * -stateForMode(OFRunLoop *self, OFRunLoopMode mode, bool create) +stateForMode(OFRunLoop *self, OFRunLoopMode mode, bool create, + bool createObserver) { OFRunLoopState *state; #ifdef OF_HAVE_THREADS [self->_statesMutex lock]; @@ -1182,10 +1183,18 @@ [self->_states setObject: state forKey: mode]; } @finally { [state release]; } } + +#ifdef OF_HAVE_SOCKETS + if (createObserver && state->_kernelEventObserver == nil) { + state->_kernelEventObserver = + [[OFKernelEventObserver alloc] init]; + state->_kernelEventObserver.delegate = state; + } +#endif #ifdef OF_HAVE_THREADS } @finally { [self->_statesMutex unlock]; } #endif @@ -1192,47 +1201,47 @@ return state; } #ifdef OF_HAVE_SOCKETS -# define NEW_READ(type, object, mode) \ - void *pool = objc_autoreleasePoolPush(); \ - OFRunLoop *runLoop = [self currentRunLoop]; \ - 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]; \ - } \ - \ - if (queue.count == 0) \ - [state->_kernelEventObserver \ - addObjectForReading: object]; \ - \ - queueItem = [[[type alloc] init] autorelease]; -# define NEW_WRITE(type, object, mode) \ - void *pool = objc_autoreleasePoolPush(); \ - OFRunLoop *runLoop = [self currentRunLoop]; \ - 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]; \ - } \ - \ - if (queue.count == 0) \ - [state->_kernelEventObserver \ - addObjectForWriting: object]; \ - \ - queueItem = [[[type alloc] init] autorelease]; -#define QUEUE_ITEM \ - [queue appendObject: queueItem]; \ - \ +# define NEW_READ(type, object, mode) \ + void *pool = objc_autoreleasePoolPush(); \ + OFRunLoop *runLoop = [self currentRunLoop]; \ + OFRunLoopState *state = stateForMode(runLoop, mode, true, true); \ + OFList *queue = [state->_readQueues objectForKey: object]; \ + type *queueItem; \ + \ + if (queue == nil) { \ + queue = [OFList list]; \ + [state->_readQueues setObject: queue forKey: object]; \ + } \ + \ + if (queue.count == 0) \ + [state->_kernelEventObserver \ + addObjectForReading: object]; \ + \ + queueItem = [[[type alloc] init] autorelease]; +# define NEW_WRITE(type, object, mode) \ + void *pool = objc_autoreleasePoolPush(); \ + OFRunLoop *runLoop = [self currentRunLoop]; \ + OFRunLoopState *state = stateForMode(runLoop, mode, true, true); \ + OFList *queue = [state->_writeQueues objectForKey: object]; \ + type *queueItem; \ + \ + if (queue == nil) { \ + queue = [OFList list]; \ + [state->_writeQueues setObject: queue forKey: object]; \ + } \ + \ + if (queue.count == 0) \ + [state->_kernelEventObserver \ + addObjectForWriting: object]; \ + \ + queueItem = [[[type alloc] init] autorelease]; +#define QUEUE_ITEM \ + [queue appendObject: queueItem]; \ + \ objc_autoreleasePoolPop(pool); + (void)of_addAsyncReadForStream: (OFStream *) stream buffer: (void *)buffer @@ -1499,11 +1508,11 @@ + (void)of_cancelAsyncRequestsForObject: (id)object mode: (OFRunLoopMode)mode { void *pool = objc_autoreleasePoolPush(); OFRunLoop *runLoop = [self currentRunLoop]; - OFRunLoopState *state = stateForMode(runLoop, mode, false); + OFRunLoopState *state = stateForMode(runLoop, mode, false, false); OFList *queue; if (state == nil) return; @@ -1579,11 +1588,11 @@ [self addTimer: timer forMode: OFDefaultRunLoopMode]; } - (void)addTimer: (OFTimer *)timer forMode: (OFRunLoopMode)mode { - OFRunLoopState *state = stateForMode(self, mode, true); + OFRunLoopState *state = stateForMode(self, mode, true, false); #ifdef OF_HAVE_THREADS [state->_timersQueueMutex lock]; @try { #endif @@ -1594,20 +1603,21 @@ } #endif [timer of_setInRunLoop: self mode: mode]; -#if defined(OF_HAVE_SOCKETS) +#ifdef OF_HAVE_SOCKETS [state->_kernelEventObserver cancel]; -#elif defined(OF_HAVE_THREADS) +#endif +#ifdef OF_HAVE_THREADS [state->_condition signal]; #endif } - (void)of_removeTimer: (OFTimer *)timer forMode: (OFRunLoopMode)mode { - OFRunLoopState *state = stateForMode(self, mode, false); + OFRunLoopState *state = stateForMode(self, mode, false, false); /* {} required to avoid -Wmisleading-indentation false positive. */ if (state == nil) { return; } @@ -1642,11 +1652,11 @@ - (void)addExecSignal: (ULONG)signal forMode: (OFRunLoopMode)mode target: (id)target selector: (SEL)selector { - OFRunLoopState *state = stateForMode(self, mode, true); + OFRunLoopState *state = stateForMode(self, mode, true, false); # ifdef OF_HAVE_THREADS [state->_execSignalsMutex lock]; @try { # endif @@ -1654,22 +1664,24 @@ [state->_execSignalsTargets addObject: target]; [state->_execSignalsSelectors addItem: &selector]; # ifdef OF_HAVE_SOCKETS state->_kernelEventObserver.execSignalMask |= (1ul << signal); -# elif defined(OF_HAVE_THREADS) +# endif +# ifdef OF_HAVE_THREADS state->_execSignalMask |= (1ul << signal); # endif # ifdef OF_HAVE_THREADS } @finally { [state->_execSignalsMutex unlock]; } # endif -# if defined(OF_HAVE_SOCKETS) +# ifdef OF_HAVE_SOCKETS [state->_kernelEventObserver cancel]; -# elif defined(OF_HAVE_THREADS) +# endif +# ifdef OF_HAVE_THREADS [state->_condition signal]; # endif } - (void)removeExecSignal: (ULONG)signal @@ -1685,11 +1697,11 @@ - (void)removeExecSignal: (ULONG)signal forMode: (OFRunLoopMode)mode target: (id)target selector: (SEL)selector { - OFRunLoopState *state = stateForMode(self, mode, false); + OFRunLoopState *state = stateForMode(self, mode, false, false); if (state == nil) return; # ifdef OF_HAVE_THREADS @@ -1717,22 +1729,24 @@ newMask |= (1ul << signals[i]); } # ifdef OF_HAVE_SOCKETS state->_kernelEventObserver.execSignalMask = newMask; -# elif defined(OF_HAVE_THREADS) +# endif +# ifdef OF_HAVE_THREADS state->_execSignalMask = newMask; # endif # ifdef OF_HAVE_THREADS } @finally { [state->_execSignalsMutex unlock]; } # endif -# if defined(OF_HAVE_SOCKETS) +# ifdef OF_HAVE_SOCKETS [state->_kernelEventObserver cancel]; -# elif defined(OF_HAVE_THREADS) +# endif +# ifdef OF_HAVE_THREADS [state->_condition signal]; # endif } #endif @@ -1752,19 +1766,19 @@ - (void)runMode: (OFRunLoopMode)mode beforeDate: (OFDate *)deadline { void *pool = objc_autoreleasePoolPush(); OFRunLoopMode previousMode = _currentMode; - OFRunLoopState *state = stateForMode(self, mode, false); + OFRunLoopState *state = stateForMode(self, mode, false, false); if (state == nil) return; _currentMode = mode; @try { OFDate *nextTimer; -#if defined(OF_AMIGAOS) && !defined(OF_HAVE_SOCKETS) && defined(OF_HAVE_THREADS) +#if defined(OF_AMIGAOS) && defined(OF_HAVE_THREADS) ULONG signalMask; #endif for (;;) { OFTimer *timer; @@ -1823,63 +1837,82 @@ timeout = deadline.timeIntervalSinceNow; else timeout = [nextTimer earlierDate: deadline] .timeIntervalSinceNow; - if (timeout < 0) + if (timeout < 0) { timeout = 0; - -#if defined(OF_HAVE_SOCKETS) - @try { - [state->_kernelEventObserver - observeForTimeInterval: timeout]; - } @catch (OFObserveKernelEventsFailedException *e) { - if (e.errNo != EINTR) - @throw e; - } -#elif defined(OF_HAVE_THREADS) - [state->_condition lock]; + } + +#ifdef OF_HAVE_SOCKETS + if (state->_kernelEventObserver != nil) { + @try { + [state->_kernelEventObserver + observeForTimeInterval: timeout]; + } @catch (OFObserveKernelEventsFailedException + *e) { + if (e.errNo != EINTR) + @throw e; + } + } else { +#endif +#ifdef OF_HAVE_THREADS + [state->_condition lock]; # ifdef OF_AMIGAOS - signalMask = state->_execSignalMask; - [state->_condition waitForTimeInterval: timeout - orExecSignal: &signalMask]; - if (signalMask != 0) - [state execSignalWasReceived: signalMask]; + signalMask = state->_execSignalMask; + [state->_condition + waitForTimeInterval: timeout + orExecSignal: &signalMask]; + if (signalMask != 0) + [state + execSignalWasReceived: signalMask]; # else - [state->_condition waitForTimeInterval: timeout]; + [state->_condition + waitForTimeInterval: timeout]; # endif - [state->_condition unlock]; + [state->_condition unlock]; #else - [OFThread sleepForTimeInterval: timeout]; + [OFThread sleepForTimeInterval: timeout]; +#endif +#ifdef OF_HAVE_SOCKETS + } #endif } else { /* * No more timers and no deadline: Just watch for I/O * until we get an event. If a timer is added by * another thread, it cancels the observe. */ -#if defined(OF_HAVE_SOCKETS) - @try { - [state->_kernelEventObserver observe]; - } @catch (OFObserveKernelEventsFailedException *e) { - if (e.errNo != EINTR) - @throw e; - } -#elif defined(OF_HAVE_THREADS) - [state->_condition lock]; +#ifdef OF_HAVE_SOCKETS + if (state->_kernelEventObserver != nil) { + @try { + [state->_kernelEventObserver observe]; + } @catch (OFObserveKernelEventsFailedException + *e) { + if (e.errNo != EINTR) + @throw e; + } + } else { +#endif +#ifdef OF_HAVE_THREADS + [state->_condition lock]; # ifdef OF_AMIGAOS - signalMask = state->_execSignalMask; - [state->_condition - waitForConditionOrExecSignal: &signalMask]; - if (signalMask != 0) - [state execSignalWasReceived: signalMask]; + signalMask = state->_execSignalMask; + [state->_condition + waitForConditionOrExecSignal: &signalMask]; + if (signalMask != 0) + [state + execSignalWasReceived: signalMask]; # else - [state->_condition wait]; + [state->_condition wait]; # endif - [state->_condition unlock]; + [state->_condition unlock]; #else - [OFThread sleepForTimeInterval: 86400]; + [OFThread sleepForTimeInterval: 86400]; +#endif +#ifdef OF_HAVE_SOCKETS + } #endif } objc_autoreleasePoolPop(pool); } @finally { @@ -1887,19 +1920,21 @@ } } - (void)stop { - OFRunLoopState *state = stateForMode(self, OFDefaultRunLoopMode, false); + OFRunLoopState *state = stateForMode(self, OFDefaultRunLoopMode, + false, false); _stop = true; if (state == nil) return; -#if defined(OF_HAVE_SOCKETS) +#ifdef OF_HAVE_SOCKETS [state->_kernelEventObserver cancel]; -#elif defined(OF_HAVE_THREADS) +#endif +#ifdef OF_HAVE_THREADS [state->_condition signal]; #endif } @end Index: src/OFSequencedPacketSocket.m ================================================================== --- src/OFSequencedPacketSocket.m +++ src/OFSequencedPacketSocket.m @@ -49,20 +49,10 @@ #import "OFWriteFailedException.h" @implementation OFSequencedPacketSocket @synthesize listening = _listening, delegate = _delegate; -+ (void)initialize -{ - if (self != [OFSequencedPacketSocket class]) - return; - - if (!_OFSocketInit()) - @throw [OFInitializationFailedException - exceptionWithClass: self]; -} - + (instancetype)socket { return [[[self alloc] init] autorelease]; } @@ -74,10 +64,14 @@ if (self.class == [OFSequencedPacketSocket class]) { [self doesNotRecognizeSelector: _cmd]; abort(); } + if (!_OFSocketInit()) + @throw [OFInitializationFailedException + exceptionWithClass: self.class]; + _socket = OFInvalidSocketHandle; _canBlock = true; } @catch (id e) { [self release]; @throw e; Index: src/OFStreamSocket.m ================================================================== --- src/OFStreamSocket.m +++ src/OFStreamSocket.m @@ -53,20 +53,10 @@ @implementation OFStreamSocket @dynamic delegate; @synthesize listening = _listening; -+ (void)initialize -{ - if (self != [OFStreamSocket class]) - return; - - if (!_OFSocketInit()) - @throw [OFInitializationFailedException - exceptionWithClass: self]; -} - + (instancetype)socket { return [[[self alloc] init] autorelease]; } @@ -78,10 +68,14 @@ if (self.class == [OFStreamSocket class]) { [self doesNotRecognizeSelector: _cmd]; abort(); } + if (!_OFSocketInit()) + @throw [OFInitializationFailedException + exceptionWithClass: self.class]; + _socket = OFInvalidSocketHandle; #ifdef OF_AMIGAOS _socketID = -1; #endif } @catch (id e) {