@@ -43,17 +43,19 @@ - init { self = [super init]; @try { - struct pollfd p = { 0, POLLIN, 0 }; + struct pollfd p = { _cancelFD[0], POLLIN, 0 }; _FDs = [[OFDataArray alloc] initWithItemSize: sizeof(struct pollfd)]; - - p.fd = _cancelFD[0]; [_FDs addItem: &p]; + + _maxFD = _cancelFD[0]; + _FDToObject = [self allocMemoryWithSize: sizeof(id) + count: _maxFD + 1]; } @catch (id e) { [self release]; @throw e; } @@ -65,12 +67,13 @@ [_FDs release]; [super dealloc]; } -- (void)OF_addFileDescriptor: (int)fd - withEvents: (short)events +- (void)OF_addObject: (id)object + fileDescriptor: (int)fd + events: (short)events { struct pollfd *FDs = [_FDs items]; size_t i, count = [_FDs count]; bool found = false; @@ -82,54 +85,73 @@ } } if (!found) { struct pollfd p = { fd, events, 0 }; + + if (fd > _maxFD) { + _maxFD = fd; + _FDToObject = [self resizeMemory: _FDToObject + size: sizeof(id) + count: _maxFD + 1]; + } + + _FDToObject[fd] = object; [_FDs addItem: &p]; } } -- (void)OF_removeFileDescriptor: (int)fd - withEvents: (short)events +- (void)OF_removeObject: (id)object + fileDescriptor: (int)fd + events: (short)events { struct pollfd *FDs = [_FDs items]; size_t i, nFDs = [_FDs count]; for (i = 0; i < nFDs; i++) { if (FDs[i].fd == fd) { FDs[i].events &= ~events; - if (FDs[i].events == 0) + if (FDs[i].events == 0) { + /* + * TODO: Remove from and resize _FDToObject, + * adjust _maxFD. + */ [_FDs removeItemAtIndex: i]; + } break; } } } -- (void)OF_addFileDescriptorForReading: (int)fd -{ - [self OF_addFileDescriptor: fd - withEvents: POLLIN]; -} - -- (void)OF_addFileDescriptorForWriting: (int)fd -{ - [self OF_addFileDescriptor: fd - withEvents: POLLOUT]; -} - -- (void)OF_removeFileDescriptorForReading: (int)fd -{ - [self OF_removeFileDescriptor: fd - withEvents: POLLIN]; -} - -- (void)OF_removeFileDescriptorForWriting: (int)fd -{ - [self OF_removeFileDescriptor: fd - withEvents: POLLOUT]; +- (void)OF_addObjectForReading: (id)object +{ + [self OF_addObject: object + fileDescriptor: [object fileDescriptorForReading] + events: POLLIN]; +} + +- (void)OF_addObjectForWriting: (id)object +{ + [self OF_addObject: object + fileDescriptor: [object fileDescriptorForWriting] + events: POLLOUT]; +} + +- (void)OF_removeObjectForReading: (id)object +{ + [self OF_removeObject: object + fileDescriptor: [object fileDescriptorForReading] + events: POLLIN]; +} + +- (void)OF_removeObjectForWriting: (id)object +{ + [self OF_removeObject: object + fileDescriptor: [object fileDescriptorForWriting] + events: POLLOUT]; } - (bool)observeForTimeInterval: (of_time_interval_t)timeInterval { void *pool = objc_autoreleasePoolPush(); @@ -163,10 +185,13 @@ if (events == 0) return false; for (i = 0; i < nFDs; i++) { + if (FDs[i].fd > _maxFD) + @throw [OFOutOfRangeException exception]; + if (FDs[i].revents & POLLIN) { if (FDs[i].fd == _cancelFD[0]) { char buffer; OF_ENSURE(read(_cancelFD[0], &buffer, 1) == 1);