ObjFW  Diff

Differences From Artifact [ea4f833523]:

To Artifact [f904878755]:


31
32
33
34
35
36
37
38
39


40
41

42
43
44
45
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
74
75
76
77
78
79
80



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96



97
98
99
100



101
102
103
104
105
106
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
142


143
144

145
146
147
148
149
150
151

152
153
154
155
156
157
158
159
160


161
162
163
164
165
166
167
168


169
170

171
172
173
174
175
176


177
178

179
180
181
182
183
184
185
31
32
33
34
35
36
37


38
39
40

41
42
43
44
45
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
74
75
76
77



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93



94
95
96
97



98
99
100
101
102
103
104
105
106
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


142
143
144

145
146
147
148
149
150
151

152
153
154
155
156
157
158
159


160
161
162
163
164
165
166
167


168
169
170

171
172
173
174
175


176
177
178

179
180
181
182
183
184
185
186







-
-
+
+

-
+






-
-
+
+




-
-
+
+




-
+

-
-
+
+




-
+

-
-
+
+






-
-
-
+
+
+













-
-
-
+
+
+

-
-
-
+
+
+











-
+



-
+


-
+

-
+
+



-
-
+
+






-
-
+
+

-
+




-
-
+
+

-
+






-
+







-
-
+
+






-
-
+
+

-
+




-
-
+
+

-
+







#import "macros.h"

@implementation OFStreamObserver_select
- init
{
	self = [super init];

	FD_ZERO(&readFDs);
	FD_ZERO(&writeFDs);
	FD_ZERO(&_readFDs);
	FD_ZERO(&_writeFDs);

	FD_SET(cancelFD[0], &readFDs);
	FD_SET(_cancelFD[0], &_readFDs);

	return self;
}

- (void)OF_addFileDescriptorForReading: (int)fd
{
	FD_SET(fd, &readFDs);
	FD_SET(fd, &exceptFDs);
	FD_SET(fd, &_readFDs);
	FD_SET(fd, &_exceptFDs);
}

- (void)OF_addFileDescriptorForWriting: (int)fd
{
	FD_SET(fd, &writeFDs);
	FD_SET(fd, &exceptFDs);
	FD_SET(fd, &_writeFDs);
	FD_SET(fd, &_exceptFDs);
}

- (void)OF_removeFileDescriptorForReading: (int)fd
{
	FD_CLR(fd, &readFDs);
	FD_CLR(fd, &_readFDs);

	if (!FD_ISSET(fd, &writeFDs))
		FD_CLR(fd, &exceptFDs);
	if (!FD_ISSET(fd, &_writeFDs))
		FD_CLR(fd, &_exceptFDs);
}

- (void)OF_removeFileDescriptorForWriting: (int)fd
{
	FD_CLR(fd, &writeFDs);
	FD_CLR(fd, &_writeFDs);

	if (!FD_ISSET(fd, &readFDs))
		FD_CLR(fd, &exceptFDs);
	if (!FD_ISSET(fd, &_readFDs))
		FD_CLR(fd, &_exceptFDs);
}

- (BOOL)observeWithTimeout: (double)timeout
{
	void *pool = objc_autoreleasePoolPush();
	OFStream **objects;
	fd_set readFDs_;
	fd_set writeFDs_;
	fd_set exceptFDs_;
	fd_set readFDs;
	fd_set writeFDs;
	fd_set exceptFDs;
	struct timeval time;
	size_t i, count, realEvents = 0;

	[self OF_processQueue];

	if ([self OF_processCache]) {
		objc_autoreleasePoolPop(pool);
		return YES;
	}

	objc_autoreleasePoolPop(pool);

#ifdef FD_COPY
	FD_COPY(&readFDs, &readFDs_);
	FD_COPY(&writeFDs, &writeFDs_);
	FD_COPY(&exceptFDs, &exceptFDs_);
	FD_COPY(&_readFDs, &readFDs);
	FD_COPY(&_writeFDs, &writeFDs);
	FD_COPY(&_exceptFDs, &exceptFDs);
#else
	readFDs_ = readFDs;
	writeFDs_ = writeFDs;
	exceptFDs_ = exceptFDs;
	readFDs = _readFDs;
	writeFDs = _writeFDs;
	exceptFDs = _exceptFDs;
#endif

	/*
	 * We cast to int before assigning to tv_usec in order to avoid a
	 * warning with Apple GCC on PPC. POSIX defines this as suseconds_t,
	 * however, this is not available on Win32. As an int should always
	 * satisfy the required range, we just cast to int.
	 */
	time.tv_sec = (time_t)timeout;
	time.tv_usec = (int)((timeout - time.tv_sec) * 1000);

	if (select((int)maxFD + 1, &readFDs_, &writeFDs_, &exceptFDs_,
	if (select((int)_maxFD + 1, &readFDs, &writeFDs, &exceptFDs,
	    (timeout != -1 ? &time : NULL)) < 1)
		return NO;

	if (FD_ISSET(cancelFD[0], &readFDs_)) {
	if (FD_ISSET(_cancelFD[0], &readFDs)) {
		char buffer;
#ifndef _WIN32
		OF_ENSURE(read(cancelFD[0], &buffer, 1) > 0);
		OF_ENSURE(read(_cancelFD[0], &buffer, 1) > 0);
#else
		OF_ENSURE(recvfrom(cancelFD[0], &buffer, 1, 0, NULL, NULL) > 0);
		OF_ENSURE(recvfrom(_cancelFD[0], &buffer, 1, 0, NULL,
		    NULL) > 0);
#endif
	}

	objects = [readStreams objects];
	count = [readStreams count];
	objects = [_readStreams objects];
	count = [_readStreams count];

	for (i = 0; i < count; i++) {
		int fd = [objects[i] fileDescriptorForReading];

		pool = objc_autoreleasePoolPush();

		if (FD_ISSET(fd, &readFDs_)) {
			if ([delegate respondsToSelector:
		if (FD_ISSET(fd, &readFDs)) {
			if ([_delegate respondsToSelector:
			    @selector(streamIsReadyForReading:)])
				[delegate streamIsReadyForReading: objects[i]];
				[_delegate streamIsReadyForReading: objects[i]];

			realEvents++;
		}

		if (FD_ISSET(fd, &exceptFDs_)) {
			if ([delegate respondsToSelector:
		if (FD_ISSET(fd, &exceptFDs)) {
			if ([_delegate respondsToSelector:
			    @selector(streamDidReceiveException:)])
				[delegate streamDidReceiveException:
				[_delegate streamDidReceiveException:
				    objects[i]];

			/*
			 * Prevent calling it twice in case the FD is in both
			 * sets.
			 */
			FD_CLR(fd, &exceptFDs_);
			FD_CLR(fd, &exceptFDs);

			realEvents++;
		}

		objc_autoreleasePoolPop(pool);
	}

	objects = [writeStreams objects];
	count = [writeStreams count];
	objects = [_writeStreams objects];
	count = [_writeStreams count];

	for (i = 0; i < count; i++) {
		int fd = [objects[i] fileDescriptorForWriting];

		pool = objc_autoreleasePoolPush();

		if (FD_ISSET(fd, &writeFDs_)) {
			if ([delegate respondsToSelector:
		if (FD_ISSET(fd, &writeFDs)) {
			if ([_delegate respondsToSelector:
			    @selector(streamIsReadyForWriting:)])
				[delegate streamIsReadyForWriting: objects[i]];
				[_delegate streamIsReadyForWriting: objects[i]];

			realEvents++;
		}

		if (FD_ISSET(fd, &exceptFDs_)) {
			if ([delegate respondsToSelector:
		if (FD_ISSET(fd, &exceptFDs)) {
			if ([_delegate respondsToSelector:
			    @selector(streamDidReceiveException:)])
				[delegate streamDidReceiveException:
				[_delegate streamDidReceiveException:
				    objects[i]];

			realEvents++;
		}

		objc_autoreleasePoolPop(pool);
	}