︙ | | |
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
-
+
+
-
+
|
#endif
{
@public
OFSortedList OF_GENERIC(OFTimer *) *_timersQueue;
#ifdef OF_HAVE_THREADS
OFMutex *_timersQueueMutex;
#endif
#if defined(OF_HAVE_SOCKETS)
#ifdef OF_HAVE_SOCKETS
OFKernelEventObserver *_kernelEventObserver;
OFMutableDictionary *_readQueues, *_writeQueues;
#endif
#elif defined(OF_HAVE_THREADS)
#ifdef OF_HAVE_THREADS
OFCondition *_condition;
# ifdef OF_AMIGAOS
ULONG _execSignalMask;
# endif
#endif
#ifdef OF_AMIGAOS
OFMutableData *_execSignals;
|
︙ | | |
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
|
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
|
-
+
-
-
-
+
-
+
|
@try {
_timersQueue = [[OFSortedList alloc] init];
#ifdef OF_HAVE_THREADS
_timersQueueMutex = [[OFMutex alloc] init];
#endif
#if defined(OF_HAVE_SOCKETS)
#ifdef OF_HAVE_SOCKETS
_kernelEventObserver = [[OFKernelEventObserver alloc] init];
_kernelEventObserver.delegate = self;
_readQueues = [[OFMutableDictionary alloc] init];
_writeQueues = [[OFMutableDictionary alloc] init];
#endif
#elif defined(OF_HAVE_THREADS)
#if 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]
|
︙ | | |
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
|
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
|
-
+
+
-
+
|
- (void)dealloc
{
[_timersQueue release];
#ifdef OF_HAVE_THREADS
[_timersQueueMutex release];
#endif
#if defined(OF_HAVE_SOCKETS)
#ifdef OF_HAVE_SOCKETS
[_kernelEventObserver release];
[_readQueues release];
[_writeQueues release];
#endif
#elif defined(OF_HAVE_THREADS)
#ifdef OF_HAVE_THREADS
[_condition release];
#endif
#ifdef OF_AMIGAOS
[_execSignals release];
[_execSignalsTargets release];
[_execSignalsSelectors release];
# ifdef OF_HAVE_THREADS
|
︙ | | |
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
|
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
|
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
|
+ (void)of_setMainRunLoop: (OFRunLoop *)runLoop
{
mainRunLoop = [runLoop retain];
}
static OFRunLoopState *
stateForMode(OFRunLoop *self, OFRunLoopMode mode, bool create)
stateForMode(OFRunLoop *self, OFRunLoopMode mode, bool create,
bool createObserver)
{
OFRunLoopState *state;
#ifdef OF_HAVE_THREADS
[self->_statesMutex lock];
@try {
#endif
state = [self->_states objectForKey: mode];
if (create && state == nil) {
state = [[OFRunLoopState alloc] init];
@try {
[self->_states setObject: state forKey: mode];
} @finally {
[state release];
}
}
#ifdef OF_HAVE_SOCKETS
if (createObserver && state->_kernelEventObserver == nil) {
state->_kernelEventObserver =
[[OFKernelEventObserver alloc] init];
state->_kernelEventObserver.delegate = state;
}
#endif
#ifdef OF_HAVE_THREADS
} @finally {
[self->_statesMutex unlock];
}
#endif
return state;
}
#ifdef OF_HAVE_SOCKETS
# define NEW_READ(type, object, mode) \
void *pool = objc_autoreleasePoolPush(); \
OFRunLoop *runLoop = [self currentRunLoop]; \
OFRunLoopState *state = stateForMode(runLoop, mode, true); \
OFList *queue = [state->_readQueues objectForKey: object]; \
type *queueItem; \
\
if (queue == nil) { \
queue = [OFList list]; \
[state->_readQueues setObject: queue forKey: object]; \
} \
\
if (queue.count == 0) \
[state->_kernelEventObserver \
addObjectForReading: object]; \
\
# define NEW_READ(type, object, mode) \
void *pool = objc_autoreleasePoolPush(); \
OFRunLoop *runLoop = [self currentRunLoop]; \
OFRunLoopState *state = stateForMode(runLoop, mode, true, true); \
OFList *queue = [state->_readQueues objectForKey: object]; \
type *queueItem; \
\
if (queue == nil) { \
queue = [OFList list]; \
[state->_readQueues setObject: queue forKey: object]; \
} \
\
if (queue.count == 0) \
[state->_kernelEventObserver \
addObjectForReading: object]; \
\
queueItem = [[[type alloc] init] autorelease];
# define NEW_WRITE(type, object, mode) \
void *pool = objc_autoreleasePoolPush(); \
OFRunLoop *runLoop = [self currentRunLoop]; \
OFRunLoopState *state = stateForMode(runLoop, mode, true); \
OFList *queue = [state->_writeQueues objectForKey: object]; \
type *queueItem; \
\
if (queue == nil) { \
queue = [OFList list]; \
[state->_writeQueues setObject: queue forKey: object]; \
} \
\
if (queue.count == 0) \
[state->_kernelEventObserver \
addObjectForWriting: object]; \
\
# define NEW_WRITE(type, object, mode) \
void *pool = objc_autoreleasePoolPush(); \
OFRunLoop *runLoop = [self currentRunLoop]; \
OFRunLoopState *state = stateForMode(runLoop, mode, true, true); \
OFList *queue = [state->_writeQueues objectForKey: object]; \
type *queueItem; \
\
if (queue == nil) { \
queue = [OFList list]; \
[state->_writeQueues setObject: queue forKey: object]; \
} \
\
if (queue.count == 0) \
[state->_kernelEventObserver \
addObjectForWriting: object]; \
\
queueItem = [[[type alloc] init] autorelease];
#define QUEUE_ITEM \
[queue appendObject: queueItem]; \
\
#define QUEUE_ITEM \
[queue appendObject: queueItem]; \
\
objc_autoreleasePoolPop(pool);
+ (void)of_addAsyncReadForStream: (OFStream <OFReadyForReadingObserving> *)
stream
buffer: (void *)buffer
length: (size_t)length
mode: (OFRunLoopMode)mode
|
︙ | | |
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
|
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
|
-
+
|
# undef NEW_WRITE
# undef QUEUE_ITEM
+ (void)of_cancelAsyncRequestsForObject: (id)object mode: (OFRunLoopMode)mode
{
void *pool = objc_autoreleasePoolPush();
OFRunLoop *runLoop = [self currentRunLoop];
OFRunLoopState *state = stateForMode(runLoop, mode, false);
OFRunLoopState *state = stateForMode(runLoop, mode, false, false);
OFList *queue;
if (state == nil)
return;
if ((queue = [state->_writeQueues objectForKey: object]) != nil) {
OFAssert(queue.count > 0);
|
︙ | | |
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
|
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
|
-
+
-
+
+
-
+
-
+
|
- (void)addTimer: (OFTimer *)timer
{
[self addTimer: timer forMode: OFDefaultRunLoopMode];
}
- (void)addTimer: (OFTimer *)timer forMode: (OFRunLoopMode)mode
{
OFRunLoopState *state = stateForMode(self, mode, true);
OFRunLoopState *state = stateForMode(self, mode, true, false);
#ifdef OF_HAVE_THREADS
[state->_timersQueueMutex lock];
@try {
#endif
[state->_timersQueue insertObject: timer];
#ifdef OF_HAVE_THREADS
} @finally {
[state->_timersQueueMutex unlock];
}
#endif
[timer of_setInRunLoop: self mode: mode];
#if defined(OF_HAVE_SOCKETS)
#ifdef OF_HAVE_SOCKETS
[state->_kernelEventObserver cancel];
#endif
#elif defined(OF_HAVE_THREADS)
#ifdef OF_HAVE_THREADS
[state->_condition signal];
#endif
}
- (void)of_removeTimer: (OFTimer *)timer forMode: (OFRunLoopMode)mode
{
OFRunLoopState *state = stateForMode(self, mode, false);
OFRunLoopState *state = stateForMode(self, mode, false, false);
/* {} required to avoid -Wmisleading-indentation false positive. */
if (state == nil) {
return;
}
#ifdef OF_HAVE_THREADS
|
︙ | | |
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
|
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
|
-
+
+
-
+
-
+
+
-
+
-
+
|
}
- (void)addExecSignal: (ULONG)signal
forMode: (OFRunLoopMode)mode
target: (id)target
selector: (SEL)selector
{
OFRunLoopState *state = stateForMode(self, mode, true);
OFRunLoopState *state = stateForMode(self, mode, true, false);
# 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);
# endif
# elif defined(OF_HAVE_THREADS)
# ifdef OF_HAVE_THREADS
state->_execSignalMask |= (1ul << signal);
# endif
# ifdef OF_HAVE_THREADS
} @finally {
[state->_execSignalsMutex unlock];
}
# endif
# if defined(OF_HAVE_SOCKETS)
# ifdef OF_HAVE_SOCKETS
[state->_kernelEventObserver cancel];
# endif
# elif defined(OF_HAVE_THREADS)
# ifdef OF_HAVE_THREADS
[state->_condition signal];
# endif
}
- (void)removeExecSignal: (ULONG)signal
target: (id)target
selector: (SEL)selector
{
[self removeExecSignal: signal
forMode: OFDefaultRunLoopMode
target: target
selector: selector];
}
- (void)removeExecSignal: (ULONG)signal
forMode: (OFRunLoopMode)mode
target: (id)target
selector: (SEL)selector
{
OFRunLoopState *state = stateForMode(self, mode, false);
OFRunLoopState *state = stateForMode(self, mode, false, false);
if (state == nil)
return;
# ifdef OF_HAVE_THREADS
[state->_execSignalsMutex lock];
@try {
|
︙ | | |
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
|
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
|
+
-
+
-
+
+
-
+
|
found = true;
} else
newMask |= (1ul << signals[i]);
}
# ifdef OF_HAVE_SOCKETS
state->_kernelEventObserver.execSignalMask = newMask;
# endif
# elif defined(OF_HAVE_THREADS)
# ifdef OF_HAVE_THREADS
state->_execSignalMask = newMask;
# endif
# ifdef OF_HAVE_THREADS
} @finally {
[state->_execSignalsMutex unlock];
}
# endif
# if defined(OF_HAVE_SOCKETS)
# ifdef OF_HAVE_SOCKETS
[state->_kernelEventObserver cancel];
# endif
# elif defined(OF_HAVE_THREADS)
# ifdef OF_HAVE_THREADS
[state->_condition signal];
# endif
}
#endif
- (void)run
{
|
︙ | | |
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
|
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
|
-
+
-
+
|
[self runMode: OFDefaultRunLoopMode beforeDate: deadline];
}
- (void)runMode: (OFRunLoopMode)mode beforeDate: (OFDate *)deadline
{
void *pool = objc_autoreleasePoolPush();
OFRunLoopMode previousMode = _currentMode;
OFRunLoopState *state = stateForMode(self, mode, false);
OFRunLoopState *state = stateForMode(self, mode, false, false);
if (state == nil)
return;
_currentMode = mode;
@try {
OFDate *nextTimer;
#if defined(OF_AMIGAOS) && !defined(OF_HAVE_SOCKETS) && defined(OF_HAVE_THREADS)
#if defined(OF_AMIGAOS) && defined(OF_HAVE_THREADS)
ULONG signalMask;
#endif
for (;;) {
OFTimer *timer;
#ifdef OF_HAVE_THREADS
|
︙ | | |
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
|
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
|
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
+
+
-
+
-
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
-
+
-
+
-
+
+
+
+
-
+
+
-
+
+
-
+
|
timeout = nextTimer.timeIntervalSinceNow;
else if (nextTimer == nil && deadline != nil)
timeout = deadline.timeIntervalSinceNow;
else
timeout = [nextTimer earlierDate: deadline]
.timeIntervalSinceNow;
if (timeout < 0)
if (timeout < 0) {
timeout = 0;
#if defined(OF_HAVE_SOCKETS)
@try {
[state->_kernelEventObserver
observeForTimeInterval: timeout];
} @catch (OFObserveKernelEventsFailedException *e) {
if (e.errNo != EINTR)
@throw e;
}
#elif defined(OF_HAVE_THREADS)
[state->_condition lock];
}
#ifdef OF_HAVE_SOCKETS
if (state->_kernelEventObserver != nil) {
@try {
[state->_kernelEventObserver
observeForTimeInterval: timeout];
} @catch (OFObserveKernelEventsFailedException
*e) {
if (e.errNo != EINTR)
@throw e;
}
} else {
#endif
#ifdef OF_HAVE_THREADS
[state->_condition lock];
# ifdef OF_AMIGAOS
signalMask = state->_execSignalMask;
[state->_condition waitForTimeInterval: timeout
orExecSignal: &signalMask];
if (signalMask != 0)
[state execSignalWasReceived: signalMask];
signalMask = state->_execSignalMask;
[state->_condition
waitForTimeInterval: timeout
orExecSignal: &signalMask];
if (signalMask != 0)
[state
execSignalWasReceived: signalMask];
# else
[state->_condition waitForTimeInterval: timeout];
[state->_condition
waitForTimeInterval: timeout];
# endif
[state->_condition unlock];
[state->_condition unlock];
#else
[OFThread sleepForTimeInterval: timeout];
[OFThread sleepForTimeInterval: timeout];
#endif
#ifdef OF_HAVE_SOCKETS
}
#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 (OFObserveKernelEventsFailedException *e) {
if (e.errNo != EINTR)
@throw e;
}
#elif defined(OF_HAVE_THREADS)
[state->_condition lock];
#ifdef OF_HAVE_SOCKETS
if (state->_kernelEventObserver != nil) {
@try {
[state->_kernelEventObserver observe];
} @catch (OFObserveKernelEventsFailedException
*e) {
if (e.errNo != EINTR)
@throw e;
}
} else {
#endif
#ifdef OF_HAVE_THREADS
[state->_condition lock];
# ifdef OF_AMIGAOS
signalMask = state->_execSignalMask;
[state->_condition
waitForConditionOrExecSignal: &signalMask];
if (signalMask != 0)
[state execSignalWasReceived: signalMask];
signalMask = state->_execSignalMask;
[state->_condition
waitForConditionOrExecSignal: &signalMask];
if (signalMask != 0)
[state
execSignalWasReceived: signalMask];
# else
[state->_condition wait];
[state->_condition wait];
# endif
[state->_condition unlock];
[state->_condition unlock];
#else
[OFThread sleepForTimeInterval: 86400];
[OFThread sleepForTimeInterval: 86400];
#endif
#ifdef OF_HAVE_SOCKETS
}
#endif
}
objc_autoreleasePoolPop(pool);
} @finally {
_currentMode = previousMode;
}
}
- (void)stop
{
OFRunLoopState *state = stateForMode(self, OFDefaultRunLoopMode, false);
OFRunLoopState *state = stateForMode(self, OFDefaultRunLoopMode,
false, false);
_stop = true;
if (state == nil)
return;
#if defined(OF_HAVE_SOCKETS)
#ifdef OF_HAVE_SOCKETS
[state->_kernelEventObserver cancel];
#endif
#elif defined(OF_HAVE_THREADS)
#ifdef OF_HAVE_THREADS
[state->_condition signal];
#endif
}
@end
|