@@ -60,16 +60,15 @@ if ((flags = fcntl(_kernelQueue, F_GETFD, 0)) != -1) fcntl(_kernelQueue, F_SETFD, flags | FD_CLOEXEC); #endif - _changeList = [[OFDataArray alloc] initWithItemSize: - sizeof(struct kevent)]; EV_SET(&event, _cancelFD[0], EVFILT_READ, EV_ADD, 0, 0, 0); - [_changeList addItem: &event]; - _removedArray = [[OFMutableArray alloc] init]; + if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0) + @throw [OFInitializationFailedException + exceptionWithClass: [self class]]; } @catch (id e) { [self release]; @throw e; } @@ -78,23 +77,17 @@ - (void)dealloc { close(_kernelQueue); - [_changeList release]; - [_removedArray release]; - [super dealloc]; } -- (void)OF_addObjectForReading: (id)object +- (void)addObjectForReading: (id )object { struct kevent event; - if ([_changeList count] >= INT_MAX) - @throw [OFOutOfRangeException exception]; - memset(&event, 0, sizeof(event)); event.ident = [object fileDescriptorForReading]; event.filter = EVFILT_READ; event.flags = EV_ADD; #ifndef __NetBSD__ @@ -101,20 +94,20 @@ event.udata = object; #else event.udata = (intptr_t)object; #endif - [_changeList addItem: &event]; + if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0) + @throw [OFObserveFailedException + exceptionWithObserver: self + errNo: errno]; } -- (void)OF_addObjectForWriting: (id)object +- (void)addObjectForWriting: (id )object { struct kevent event; - if ([_changeList count] >= INT_MAX) - @throw [OFOutOfRangeException exception]; - memset(&event, 0, sizeof(event)); event.ident = [object fileDescriptorForWriting]; event.filter = EVFILT_WRITE; event.flags = EV_ADD; #ifndef __NetBSD__ @@ -121,33 +114,44 @@ event.udata = object; #else event.udata = (intptr_t)object; #endif - [_changeList addItem: &event]; + if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0) + @throw [OFObserveFailedException + exceptionWithObserver: self + errNo: errno]; } -- (void)OF_removeObjectForReading: (id)object +- (void)removeObjectForReading: (id )object { struct kevent event; memset(&event, 0, sizeof(event)); event.ident = [object fileDescriptorForReading]; event.filter = EVFILT_READ; event.flags = EV_DELETE; - [_changeList addItem: &event]; + + if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0) + @throw [OFObserveFailedException + exceptionWithObserver: self + errNo: errno]; } -- (void)OF_removeObjectForWriting: (id)object +- (void)removeObjectForWriting: (id )object { struct kevent event; memset(&event, 0, sizeof(event)); event.ident = [object fileDescriptorForWriting]; event.filter = EVFILT_WRITE; event.flags = EV_DELETE; - [_changeList addItem: &event]; + + if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0) + @throw [OFObserveFailedException + exceptionWithObserver: self + errNo: errno]; } - (void)observeForTimeInterval: (of_time_interval_t)timeInterval { void *pool = objc_autoreleasePoolPush(); @@ -156,31 +160,21 @@ int i, events; timeout.tv_sec = (time_t)timeInterval; timeout.tv_nsec = lrint((timeInterval - timeout.tv_sec) * 1000000000); - /* - * Make sure to keep the streams retained and thus the file descriptors - * valid until the actual change has been performed. - */ - [self OF_processQueueAndStoreRemovedIn: _removedArray]; - [self OF_processReadBuffers]; objc_autoreleasePoolPop(pool); - events = kevent(_kernelQueue, [_changeList items], - (int)[_changeList count], eventList, EVENTLIST_SIZE, + events = kevent(_kernelQueue, NULL, 0, eventList, EVENTLIST_SIZE, (timeInterval != -1 ? &timeout : NULL)); if (events < 0) @throw [OFObserveFailedException exceptionWithObserver: self errNo: errno]; - [_changeList removeAllItems]; - [_removedArray removeAllObjects]; - for (i = 0; i < events; i++) { if (eventList[i].flags & EV_ERROR) @throw [OFObserveFailedException exceptionWithObserver: self errNo: (int)eventList[i].data];