Overview
Comment: | Retain sockets until after removal from observer
Not retaining them caused kevent() to be called on an invalid fd. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
1dbe9a4e4eb722c4f4cf49b94015bb99 |
User & Date: | js on 2014-08-22 19:09:34 |
Other Links: | manifest | tags |
Context
2014-08-23
| ||
01:01 | Make ObjFW.framework a module check-in: c8a562d8d7 user: js tags: trunk | |
2014-08-22
| ||
19:09 | Retain sockets until after removal from observer check-in: 1dbe9a4e4e user: js tags: trunk | |
2014-08-21
| ||
19:00 | OFHTTPServer: Don't close the socket manually check-in: b87a5d3b46 user: js tags: trunk | |
Changes
Modified src/OFKernelEventObserver+Private.h from [9baa15c51b] to [c004806a34].
︙ | ︙ | |||
17 18 19 20 21 22 23 | #import "OFKernelEventObserver.h" @interface OFKernelEventObserver (OF_PRIVATE_CATEGORY) - (void)OF_addFileDescriptorForReading: (int)fd; - (void)OF_addFileDescriptorForWriting: (int)fd; - (void)OF_removeFileDescriptorForReading: (int)fd; - (void)OF_removeFileDescriptorForWriting: (int)fd; | | | 17 18 19 20 21 22 23 24 25 26 | #import "OFKernelEventObserver.h" @interface OFKernelEventObserver (OF_PRIVATE_CATEGORY) - (void)OF_addFileDescriptorForReading: (int)fd; - (void)OF_addFileDescriptorForWriting: (int)fd; - (void)OF_removeFileDescriptorForReading: (int)fd; - (void)OF_removeFileDescriptorForWriting: (int)fd; - (void)OF_processQueueAndStoreRemovedIn: (OFMutableArray*)removed; - (bool)OF_processCache; @end |
Modified src/OFKernelEventObserver.m from [380728b304] to [3ffd7510cd].
︙ | ︙ | |||
295 296 297 298 299 300 301 | } - (void)OF_removeFileDescriptorForWriting: (int)fd { OF_UNRECOGNIZED_SELECTOR } | | | 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 | } - (void)OF_removeFileDescriptorForWriting: (int)fd { OF_UNRECOGNIZED_SELECTOR } - (void)OF_processQueueAndStoreRemovedIn: (OFMutableArray*)removed { #ifdef OF_HAVE_THREADS [_mutex lock]; #endif @try { id const *queueObjects = [_queue objects]; int *queueInfoItems = [_queueInfo items]; |
︙ | ︙ | |||
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 | [self OF_addFileDescriptorForWriting: fd]; break; case QUEUE_REMOVE | QUEUE_READ: [self OF_removeFileDescriptorForReading: fd]; [_readObjects removeObjectIdenticalTo: object]; break; case QUEUE_REMOVE | QUEUE_WRITE: [self OF_removeFileDescriptorForWriting: fd]; [_writeObjects removeObjectIdenticalTo: object]; break; default: assert(0); } } | > > | 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 | [self OF_addFileDescriptorForWriting: fd]; break; case QUEUE_REMOVE | QUEUE_READ: [self OF_removeFileDescriptorForReading: fd]; [removed addObject: object]; [_readObjects removeObjectIdenticalTo: object]; break; case QUEUE_REMOVE | QUEUE_WRITE: [self OF_removeFileDescriptorForWriting: fd]; [removed addObject: object]; [_writeObjects removeObjectIdenticalTo: object]; break; default: assert(0); } } |
︙ | ︙ |
Modified src/OFKernelEventObserver_kqueue.h from [5026de1303] to [ca9db11f7c].
︙ | ︙ | |||
13 14 15 16 17 18 19 20 21 22 23 24 25 26 | * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFKernelEventObserver.h" @class OFDataArray; @interface OFKernelEventObserver_kqueue: OFKernelEventObserver { int _kernelQueue; OFDataArray *_changeList; } @end | > > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFKernelEventObserver.h" @class OFDataArray; @class OFMutableArray; @interface OFKernelEventObserver_kqueue: OFKernelEventObserver { int _kernelQueue; OFDataArray *_changeList; OFMutableArray *_removedArray; } @end |
Modified src/OFKernelEventObserver_kqueue.m from [76859e1d9d] to [70736e006a].
︙ | ︙ | |||
25 26 27 28 29 30 31 32 33 34 35 36 37 38 | #include <sys/event.h> #include <sys/time.h> #import "OFKernelEventObserver.h" #import "OFKernelEventObserver+Private.h" #import "OFKernelEventObserver_kqueue.h" #import "OFDataArray.h" #import "OFInitializationFailedException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "socket_helpers.h" | > | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #include <sys/event.h> #include <sys/time.h> #import "OFKernelEventObserver.h" #import "OFKernelEventObserver+Private.h" #import "OFKernelEventObserver_kqueue.h" #import "OFDataArray.h" #import "OFArray.h" #import "OFInitializationFailedException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "socket_helpers.h" |
︙ | ︙ | |||
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | @try { if ((_kernelQueue = kqueue()) == -1) @throw [OFInitializationFailedException exceptionWithClass: [self class]]; _changeList = [[OFDataArray alloc] initWithItemSize: sizeof(struct kevent)]; [self OF_addFileDescriptorForReading: _cancelFD[0]]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { close(_kernelQueue); [_changeList release]; [super dealloc]; } - (void)OF_addFileDescriptorForReading: (int)fd { struct kevent event; | > > > | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | @try { if ((_kernelQueue = kqueue()) == -1) @throw [OFInitializationFailedException exceptionWithClass: [self class]]; _changeList = [[OFDataArray alloc] initWithItemSize: sizeof(struct kevent)]; _removedArray = [[OFMutableArray alloc] init]; [self OF_addFileDescriptorForReading: _cancelFD[0]]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { close(_kernelQueue); [_changeList release]; [_removedArray release]; [super dealloc]; } - (void)OF_addFileDescriptorForReading: (int)fd { struct kevent event; |
︙ | ︙ | |||
112 113 114 115 116 117 118 | struct timespec timeout; struct kevent eventList[EVENTLIST_SIZE]; int i, events, realEvents = 0; timeout.tv_sec = (time_t)timeInterval; timeout.tv_nsec = lrint((timeInterval - timeout.tv_sec) * 1000000000); | > > > > | > > | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | struct timespec timeout; struct kevent eventList[EVENTLIST_SIZE]; int i, events, realEvents = 0; 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]; if ([self OF_processCache]) { objc_autoreleasePoolPop(pool); return true; } objc_autoreleasePoolPop(pool); events = kevent(_kernelQueue, [_changeList items], (int)[_changeList count], eventList, EVENTLIST_SIZE, (timeInterval == -1 ? NULL : &timeout)); [_removedArray removeAllObjects]; if (events < 0) return false; [_changeList removeAllItems]; if (events == 0) |
︙ | ︙ | |||
146 147 148 149 150 151 152 | continue; } realEvents++; pool = objc_autoreleasePoolPush(); | < < < < < < < < < < < < < < < < < < < < < < < < | 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | continue; } realEvents++; pool = objc_autoreleasePoolPush(); switch (eventList[i].filter) { case EVFILT_READ: if ([_delegate respondsToSelector: @selector(objectIsReadyForReading:)]) [_delegate objectIsReadyForReading: _FDToObject[eventList[i].ident]]; break; |
︙ | ︙ |
Modified src/OFKernelEventObserver_poll.m from [daca96d316] to [ab4899dd72].
︙ | ︙ | |||
129 130 131 132 133 134 135 | - (bool)observeForTimeInterval: (of_time_interval_t)timeInterval { void *pool = objc_autoreleasePoolPush(); struct pollfd *FDs; size_t i, nFDs, realEvents = 0; | | | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | - (bool)observeForTimeInterval: (of_time_interval_t)timeInterval { void *pool = objc_autoreleasePoolPush(); struct pollfd *FDs; size_t i, nFDs, realEvents = 0; [self OF_processQueueAndStoreRemovedIn: nil]; if ([self OF_processCache]) { objc_autoreleasePoolPop(pool); return true; } objc_autoreleasePoolPop(pool); |
︙ | ︙ |
Modified src/OFKernelEventObserver_select.m from [b091506593] to [23f65818a3].
︙ | ︙ | |||
68 69 70 71 72 73 74 | void *pool = objc_autoreleasePoolPush(); id const *objects; fd_set readFDs; fd_set writeFDs; struct timeval timeout; size_t i, count, realEvents = 0; | | | 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | void *pool = objc_autoreleasePoolPush(); id const *objects; fd_set readFDs; fd_set writeFDs; struct timeval timeout; size_t i, count, realEvents = 0; [self OF_processQueueAndStoreRemovedIn: nil]; if ([self OF_processCache]) { objc_autoreleasePoolPop(pool); return true; } objc_autoreleasePoolPop(pool); |
︙ | ︙ |