@@ -1,8 +1,8 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 - * Jonathan Schleifer + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 + * Jonathan Schleifer * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in @@ -25,12 +25,16 @@ #include #import "OFKernelEventObserver.h" #import "OFKernelEventObserver+Private.h" #import "OFKernelEventObserver_epoll.h" +#import "OFArray.h" #import "OFMapTable.h" #import "OFNull.h" +#ifdef OF_HAVE_THREADS +# import "OFMutex.h" +#endif #import "OFInitializationFailedException.h" #import "OFObserveFailedException.h" #define EVENTLIST_SIZE 64 @@ -87,42 +91,26 @@ - (void)OF_addObject: (id)object fileDescriptor: (int)fd events: (int)addEvents { + struct epoll_event event; intptr_t events; events = (intptr_t)[_FDToEvents valueForKey: (void*)(intptr_t)fd]; - if (events == 0) { - struct epoll_event event; - - memset(&event, 0, sizeof(event)); - event.events = addEvents; - event.data.ptr = object; - - if (epoll_ctl(_epfd, EPOLL_CTL_ADD, fd, &event) == -1) - @throw [OFObserveFailedException - exceptionWithObserver: self - errNo: errno]; - - [_FDToEvents setValue: (void*)(intptr_t)addEvents - forKey: (void*)(intptr_t)fd]; - } else { - struct epoll_event event; - - memset(&event, 0, sizeof(event)); - event.events = (int)events | addEvents; - event.data.ptr = object; - - if (epoll_ctl(_epfd, EPOLL_CTL_MOD, fd, &event) == -1) - @throw [OFObserveFailedException - exceptionWithObserver: self - errNo: errno]; - - [_FDToEvents setValue: (void*)(events | addEvents) - forKey: (void*)(intptr_t)fd]; - } + + memset(&event, 0, sizeof(event)); + event.events = (int)events | addEvents; + event.data.ptr = object; + + if (epoll_ctl(_epfd, (events == 0 ? EPOLL_CTL_ADD : EPOLL_CTL_MOD), + fd, &event) == -1) + @throw [OFObserveFailedException exceptionWithObserver: self + errNo: errno]; + + [_FDToEvents setValue: (void*)(events | addEvents) + forKey: (void*)(intptr_t)fd]; } - (void)OF_removeObject: (id)object fileDescriptor: (int)fd events: (int)removeEvents @@ -154,49 +142,48 @@ [_FDToEvents setValue: (void*)events forKey: (void*)(intptr_t)fd]; } } -- (void)OF_addObjectForReading: (id)object +- (void)OF_addObjectForReading: (id )object { [self OF_addObject: object fileDescriptor: [object fileDescriptorForReading] events: EPOLLIN]; } -- (void)OF_addObjectForWriting: (id)object +- (void)OF_addObjectForWriting: (id )object { [self OF_addObject: object fileDescriptor: [object fileDescriptorForWriting] events: EPOLLOUT]; } -- (void)OF_removeObjectForReading: (id)object +- (void)OF_removeObjectForReading: (id )object { [self OF_removeObject: object fileDescriptor: [object fileDescriptorForReading] events: EPOLLIN]; } -- (void)OF_removeObjectForWriting: (id)object +- (void)OF_removeObjectForWriting: (id )object { [self OF_removeObject: object fileDescriptor: [object fileDescriptorForWriting] events: EPOLLOUT]; } - (void)observeForTimeInterval: (of_time_interval_t)timeInterval { OFNull *nullObject = [OFNull null]; - void *pool = objc_autoreleasePoolPush(); struct epoll_event eventList[EVENTLIST_SIZE]; int i, events; - [self OF_processQueueAndStoreRemovedIn: nil]; - [self OF_processReadBuffers]; + [self OF_processQueue]; - objc_autoreleasePoolPop(pool); + if ([self OF_processReadBuffers]) + return; events = epoll_wait(_epfd, eventList, EVENTLIST_SIZE, (timeInterval != -1 ? timeInterval * 1000 : -1)); if (events < 0) @@ -212,11 +199,11 @@ continue; } if (eventList[i].events & EPOLLIN) { - pool = objc_autoreleasePoolPush(); + void *pool = objc_autoreleasePoolPush(); if ([_delegate respondsToSelector: @selector(objectIsReadyForReading:)]) [_delegate objectIsReadyForReading: eventList[i].data.ptr]; @@ -223,11 +210,11 @@ objc_autoreleasePoolPop(pool); } if (eventList[i].events & EPOLLOUT) { - pool = objc_autoreleasePoolPush(); + void *pool = objc_autoreleasePoolPush(); if ([_delegate respondsToSelector: @selector(objectIsReadyForWriting:)]) [_delegate objectIsReadyForWriting: eventList[i].data.ptr];