︙ | | | ︙ | |
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#include "config.h"
#include <assert.h>
#include <errno.h>
#import "OFRunLoop.h"
#import "OFRunLoop+Private.h"
#import "OFData.h"
#import "OFDictionary.h"
#ifdef OF_HAVE_SOCKETS
# import "OFKernelEventObserver.h"
# import "OFTCPSocket.h"
# import "OFTCPSocket+Private.h"
#endif
|
>
|
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#include "config.h"
#include <assert.h>
#include <errno.h>
#import "OFRunLoop.h"
#import "OFRunLoop+Private.h"
#import "OFArray.h"
#import "OFData.h"
#import "OFDictionary.h"
#ifdef OF_HAVE_SOCKETS
# import "OFKernelEventObserver.h"
# import "OFTCPSocket.h"
# import "OFTCPSocket+Private.h"
#endif
|
︙ | | | ︙ | |
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
OFMutex *_timersQueueMutex;
#endif
#if defined(OF_HAVE_SOCKETS)
OFKernelEventObserver *_kernelEventObserver;
OFMutableDictionary *_readQueues, *_writeQueues;
#elif defined(OF_HAVE_THREADS)
OFCondition *_condition;
#endif
}
@end
@interface OFRunLoop ()
- (OFRunLoopState *)of_stateForMode: (of_run_loop_mode_t)mode
create: (bool)create;
|
>
>
>
>
>
>
>
>
>
>
>
|
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
OFMutex *_timersQueueMutex;
#endif
#if defined(OF_HAVE_SOCKETS)
OFKernelEventObserver *_kernelEventObserver;
OFMutableDictionary *_readQueues, *_writeQueues;
#elif defined(OF_HAVE_THREADS)
OFCondition *_condition;
# ifdef OF_AMIGAOS
ULONG _execSignalMask;
# endif
#endif
#ifdef OF_AMIGAOS
OFMutableData *_execSignals;
OFMutableArray *_execSignalsTargets;
OFMutableData *_execSignalsSelectors;
# ifdef OF_HAVE_THREADS
OFMutex *_execSignalsMutex;
# endif
#endif
}
@end
@interface OFRunLoop ()
- (OFRunLoopState *)of_stateForMode: (of_run_loop_mode_t)mode
create: (bool)create;
|
︙ | | | ︙ | |
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
_kernelEventObserver = [[OFKernelEventObserver alloc] init];
_kernelEventObserver.delegate = self;
_readQueues = [[OFMutableDictionary alloc] init];
_writeQueues = [[OFMutableDictionary alloc] init];
#elif defined(OF_HAVE_THREADS)
_condition = [[OFCondition alloc] init];
#endif
} @catch (id e) {
[self release];
@throw e;
}
return self;
|
>
>
>
>
>
>
>
>
>
>
|
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
|
_kernelEventObserver = [[OFKernelEventObserver alloc] init];
_kernelEventObserver.delegate = self;
_readQueues = [[OFMutableDictionary alloc] init];
_writeQueues = [[OFMutableDictionary alloc] init];
#elif defined(OF_HAVE_THREADS)
_condition = [[OFCondition alloc] init];
#endif
#ifdef OF_AMIGAOS
_execSignals = [[OFMutableData alloc]
initWithItemSize: sizeof(ULONG)];
_execSignalsTargets = [[OFMutableArray alloc] init];
_execSignalsSelectors = [[OFMutableData alloc]
initWithItemSize: sizeof(SEL)];
# ifdef OF_HAVE_THREADS
_execSignalsMutex = [[OFMutex alloc] init];
# endif
#endif
} @catch (id e) {
[self release];
@throw e;
}
return self;
|
︙ | | | ︙ | |
209
210
211
212
213
214
215
216
217
218
219
220
221
222
|
#endif
#if defined(OF_HAVE_SOCKETS)
[_kernelEventObserver release];
[_readQueues release];
[_writeQueues release];
#elif defined(OF_HAVE_THREADS)
[_condition release];
#endif
[super dealloc];
}
#ifdef OF_HAVE_SOCKETS
- (void)objectIsReadyForReading: (id)object
|
>
>
>
>
>
>
>
>
|
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
|
#endif
#if defined(OF_HAVE_SOCKETS)
[_kernelEventObserver release];
[_readQueues release];
[_writeQueues release];
#elif defined(OF_HAVE_THREADS)
[_condition release];
#endif
#ifdef OF_AMIGAOS
[_execSignals release];
[_execSignalsTargets release];
[_execSignalsSelectors release];
# ifdef OF_HAVE_THREADS
[_execSignalsMutex release];
# endif
#endif
[super dealloc];
}
#ifdef OF_HAVE_SOCKETS
- (void)objectIsReadyForReading: (id)object
|
︙ | | | ︙ | |
302
303
304
305
306
307
308
309
310
311
312
313
314
315
|
}
}
} @finally {
[queue release];
}
}
#endif
@end
#ifdef OF_HAVE_SOCKETS
@implementation OFRunLoopQueueItem
- (bool)handleObject: (id)object
{
OF_UNRECOGNIZED_SELECTOR
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
|
}
}
} @finally {
[queue release];
}
}
#endif
#ifdef OF_AMIGAOS
- (void)execSignalWasReceived: (ULONG)signalMask
{
void *pool = objc_autoreleasePoolPush();
OFData *signals;
OFArray *targets;
OFData *selectors;
const ULONG *signalsItems;
const id *targetsObjects;
const SEL *selectorsItems;
size_t count;
# ifdef OF_HAVE_THREADS
[_execSignalsMutex lock];
@try {
# endif
/*
* Create copies, so that signal handlers are allowed to modify
* signals.
*/
signals = [[_execSignals copy] autorelease];
targets = [[_execSignalsTargets copy] autorelease];
selectors = [[_execSignalsSelectors copy] autorelease];
# ifdef OF_HAVE_THREADS
} @finally {
[_execSignalsMutex unlock];
}
# endif
signalsItems = signals.items;
targetsObjects = targets.objects;
selectorsItems = selectors.items;
count = signals.count;
for (size_t i = 0; i < count; i++) {
if (signalMask & (1ul << signalsItems[i])) {
void (*callback)(id, SEL, ULONG) =
(void (*)(id, SEL, ULONG))[targetsObjects[i]
methodForSelector: selectorsItems[i]];
callback(targetsObjects[i], selectorsItems[i],
signalsItems[i]);
}
}
objc_autoreleasePoolPop(pool);
}
#endif
@end
#ifdef OF_HAVE_SOCKETS
@implementation OFRunLoopQueueItem
- (bool)handleObject: (id)object
{
OF_UNRECOGNIZED_SELECTOR
|
︙ | | | ︙ | |
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
|
}
#ifdef OF_HAVE_THREADS
} @finally {
[state->_timersQueueMutex unlock];
}
#endif
}
- (void)run
{
[self runUntilDate: nil];
}
- (void)runUntilDate: (OFDate *)deadline
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
|
}
#ifdef OF_HAVE_THREADS
} @finally {
[state->_timersQueueMutex unlock];
}
#endif
}
#ifdef OF_AMIGAOS
- (void)addExecSignal: (ULONG)signal
target: (id)target
selector: (SEL)selector
{
[self addExecSignal: signal
forMode: of_run_loop_mode_default
target: target
selector: selector];
}
- (void)addExecSignal: (ULONG)signal
forMode: (of_run_loop_mode_t)mode
target: (id)target
selector: (SEL)selector
{
OFRunLoopState *state = [self of_stateForMode: mode
create: true];
# ifdef OF_HAVE_THREADS
[state->_execSignalsMutex lock];
@try {
# endif
[state->_execSignals addItem: &signal];
[state->_execSignalsTargets addObject: target];
[state->_execSignalsSelectors addItem: &selector];
# ifdef OF_HAVE_SOCKETS
state->_kernelEventObserver.execSignalMask |= (1ul << signal);
# elif defined(OF_HAVE_THREADS)
state->_execSignalMask |= (1ul << signal);
# endif
# ifdef OF_HAVE_THREADS
} @finally {
[state->_execSignalsMutex unlock];
}
# endif
# if defined(OF_HAVE_SOCKETS)
[state->_kernelEventObserver cancel];
# elif defined(OF_HAVE_THREADS)
[state->_condition signal];
# endif
}
- (void)removeExecSignal: (ULONG)signal
target: (id)target
selector: (SEL)selector
{
[self removeExecSignal: signal
forMode: of_run_loop_mode_default
target: target
selector: selector];
}
- (void)removeExecSignal: (ULONG)signal
forMode: (of_run_loop_mode_t)mode
target: (id)target
selector: (SEL)selector
{
OFRunLoopState *state = [self of_stateForMode: mode
create: false];
if (state == nil)
return;
# ifdef OF_HAVE_THREADS
[state->_execSignalsMutex lock];
@try {
# endif
const ULONG *signals = state->_execSignals.items;
const id *targets = state->_execSignalsTargets.objects;
const SEL *selectors = state->_execSignalsSelectors.items;
size_t count = state->_execSignals.count;
bool found = false;
ULONG newMask = 0;
for (size_t i = 0; i < count; i++) {
if (!found && signals[i] == signal &&
targets[i] == target && selectors[i] == selector) {
[state->_execSignals removeItemAtIndex: i];
[state->_execSignalsTargets
removeObjectAtIndex: i];
[state->_execSignalsSelectors
removeItemAtIndex: i];
found = true;
} else
newMask |= (1ul << signals[i]);
}
# ifdef OF_HAVE_SOCKETS
state->_kernelEventObserver.execSignalMask = newMask;
# elif defined(OF_HAVE_THREADS)
state->_execSignalMask = newMask;
# endif
# ifdef OF_HAVE_THREADS
} @finally {
[state->_execSignalsMutex unlock];
}
# endif
# if defined(OF_HAVE_SOCKETS)
[state->_kernelEventObserver cancel];
# elif defined(OF_HAVE_THREADS)
[state->_condition signal];
# endif
}
#endif
- (void)run
{
[self runUntilDate: nil];
}
- (void)runUntilDate: (OFDate *)deadline
|
︙ | | | ︙ | |
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
|
if (state == nil)
return;
_currentMode = mode;
@try {
OFDate *nextTimer;
for (;;) {
OFTimer *timer;
#ifdef OF_HAVE_THREADS
[state->_timersQueueMutex lock];
@try {
|
>
>
>
|
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
|
if (state == nil)
return;
_currentMode = mode;
@try {
OFDate *nextTimer;
#if defined(OF_AMIGAOS) && !defined(OF_HAVE_SOCKETS) && defined(OF_HAVE_THREADS)
ULONG signalMask;
#endif
for (;;) {
OFTimer *timer;
#ifdef OF_HAVE_THREADS
[state->_timersQueueMutex lock];
@try {
|
︙ | | | ︙ | |
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
|
observeForTimeInterval: timeout];
} @catch (OFObserveFailedException *e) {
if (e.errNo != EINTR)
@throw e;
}
#elif defined(OF_HAVE_THREADS)
[state->_condition lock];
[state->_condition waitForTimeInterval: timeout];
[state->_condition unlock];
#else
[OFThread sleepForTimeInterval: timeout];
#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 (OFObserveFailedException *e) {
if (e.errNo != EINTR)
@throw e;
}
#elif defined(OF_HAVE_THREADS)
[state->_condition lock];
[state->_condition wait];
[state->_condition unlock];
#else
[OFThread sleepForTimeInterval: 86400];
#endif
}
objc_autoreleasePoolPop(pool);
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
|
observeForTimeInterval: timeout];
} @catch (OFObserveFailedException *e) {
if (e.errNo != EINTR)
@throw e;
}
#elif defined(OF_HAVE_THREADS)
[state->_condition lock];
# ifdef OF_AMIGAOS
signalMask = state->_execSignalMask;
[state->_condition waitForTimeInterval: timeout
orExecSignal: &signalMask];
if (signalMask != 0)
[state execSignalWasReceived: signalMask];
# else
[state->_condition waitForTimeInterval: timeout];
# endif
[state->_condition unlock];
#else
[OFThread sleepForTimeInterval: timeout];
#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 (OFObserveFailedException *e) {
if (e.errNo != EINTR)
@throw e;
}
#elif defined(OF_HAVE_THREADS)
[state->_condition lock];
# ifdef OF_AMIGAOS
signalMask = state->_execSignalMask;
[state->_condition
waitForConditionOrExecSignal: &signalMask];
if (signalMask != 0)
[state execSignalWasReceived: signalMask];
# else
[state->_condition wait];
# endif
[state->_condition unlock];
#else
[OFThread sleepForTimeInterval: 86400];
#endif
}
objc_autoreleasePoolPop(pool);
|
︙ | | | ︙ | |