ObjFW  Check-in [df53f06922]

Overview
Comment:Run loops have a stream observer now.

This makes async I/O possible!

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: df53f069226659d92ba7f11d122ec41bea0e0070d5d3fa0fcaf2858a37793fb2
User & Date: js on 2012-09-12 06:11:46
Other Links: manifest | tags
Context
2012-09-12
06:41
OFRunLoop: Reduce the time the lock is held. check-in: 34e548c51d user: js tags: trunk
06:11
Run loops have a stream observer now. check-in: df53f06922 user: js tags: trunk
06:11
OFRunLoop: Remove timer before possible read. check-in: 55e7d380e4 user: js tags: trunk
Changes

Modified src/OFRunLoop.h from [8d3f82ba8f] to [00fc6ba68c].

13
14
15
16
17
18
19

20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36







+








+







 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFObject.h"

@class OFSortedList;
@class OFStreamObserver;
@class OFTimer;

/**
 * \brief A class providing a run loop for the application and its processes.
 */
@interface OFRunLoop: OFObject
{
	OFSortedList *timersQueue;
	OFStreamObserver *streamObserver;
}

/**
 * \brief Returns the main run loop.
 *
 * \return The main run loop
 */

Modified src/OFRunLoop.m from [30c14bee93] to [af64aebbb7].

17
18
19
20
21
22
23

24
25
26
27
28
29
30
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31







+







#include "config.h"

#import "OFRunLoop.h"
#import "OFThread.h"
#import "OFSortedList.h"
#import "OFTimer.h"
#import "OFDate.h"
#import "OFStreamObserver.h"

static OFTLSKey *currentRunLoopKey;
static OFRunLoop *mainRunLoop;

@implementation OFRunLoop
+ (void)initialize
{
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
78
79
80
81
82

83
84
85
86
87
88
89
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94







+
+















+









+







{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();

		timersQueue = [[[OFThread currentThread] _timersQueue] retain];
		streamObserver = [[OFStreamObserver alloc] init];

		[OFThread setObject: self
			  forTLSKey: currentRunLoopKey];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[timersQueue release];
	[streamObserver release];

	[super dealloc];
}

- (void)addTimer: (OFTimer*)timer
{
	@synchronized (timersQueue) {
		[timersQueue addObject: timer];
	}
	[streamObserver cancel];
}

- (void)run
{
	for (;;) {
		void *pool = objc_autoreleasePoolPush();
		OFDate *now = [OFDate date];
107
108
109
110
111
112
113
114
115


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
112
113
114
115
116
117
118


119
120



121
122
123
124
125









126




127
128
129

130
131
132
133
134
135
136
137







-
-
+
+
-
-
-
+
+
+
+

-
-
-
-
-
-
-
-
-
+
-
-
-
-
+
+

-
+







				[timersQueue removeListObject: iter];

				[timer fire];

				objc_autoreleasePoolPop(pool2);
			}

			/* Sleep until we reach the next timer */
			if (iter != NULL)
			/* Watch for stream events till the next timer is due */
			if (iter != NULL) {
				[OFThread sleepUntilDate:
				    [iter->object fireDate]];
			else {
				double timeout = [[iter->object fireDate]
				    timeIntervalSinceNow];
				[streamObserver observeWithTimeout: timeout];
			} else {
				/*
				 * FIXME:
				 * Theoretically, another thread could add
				 * something to the run loop. This means we
				 * would need a way to block the thread until
				 * another event is added. The most easy way to
				 * achieve that would be if a run loop also
				 * handles streams: An OFStreamObserver could
				 * be called instead of sleepUntilDate above
				 * and get a timeout. If no timers are left,
				 * No more timers: Just watch for streams until
				 * it could be called without a timeout and
				 * would automatically stop blocking once a new
				 * stream is added. This could also be used to
				 * stop blocking once a new timer is added.
				 * we get an event. If a timer is added by
				 * another thread, it cancels the observe.
				 */
				[OFThread sleepForTimeInterval: 24 * 3600];
				[streamObserver observe];
			}
		}

		objc_autoreleasePoolPop(pool);
	}
}
@end