ObjFW  Check-in [1edb3cb8c7]

Overview
Comment:Don't use EV_RECEIPT.

EV_RECEIPT is not available on all systems implementing kqueue.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 1edb3cb8c7cfb67261b6039e86ae48c7c5ef4071448c1a3256aed82c1345fa30
User & Date: js on 2011-09-22 03:10:26
Other Links: manifest | tags
Context
2011-09-22
12:09
Make it impossible to add objects to arbitrary autorelease pools. check-in: 2e484248de user: js tags: trunk
03:10
Don't use EV_RECEIPT. check-in: 1edb3cb8c7 user: js tags: trunk
02:23
D'oh, stupid typo. check-in: 08700d08a6 user: js tags: trunk
Changes

Modified src/OFStreamObserver.h from [b87bb931e4] to [429a39bc00].

175
176
177
178
179
180
181




182
183
184
185
186
187
188
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192







+
+
+
+







 *
 * \param timeout The time to wait for an event, in milliseconds
 * \return A boolean whether events occurred during the timeinterval
 */
- (BOOL)observeWithTimeout: (int)timeout;

/// \cond internal
- (void)_addFileDescriptorForReading: (int)fd;
- (void)_addFileDescriptorForWriting: (int)fd;
- (void)_removeFileDescriptorForReading: (int)fd;
- (void)_removeFileDescriptorForWriting: (int)fd;
- (void)_processQueue;
- (BOOL)_processCache;
/// \endcond
@end

@interface OFObject (OFStreamObserverDelegate) <OFStreamObserverDelegate>
@end

Modified src/OFStreamObserver_kqueue.h from [e08f6267e6] to [81ae2dacc1].

11
12
13
14
15
16
17


18
19
20
21
22
23

24
25
11
12
13
14
15
16
17
18
19
20
21
22
23


24
25
26







+
+




-
-
+


 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFStreamObserver.h"

@class OFDataArray;

@interface OFStreamObserver_kqueue: OFStreamObserver
{
	int kernelQueue;
	int FDs;
	struct kevent *eventList;
	OFDataArray *changeList;
}
@end

Modified src/OFStreamObserver_kqueue.m from [828093c668] to [24c0cc0a69].

13
14
15
16
17
18
19

20
21
22
23
24
25
26
27
28
29
30
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
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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







+













-
+
-
-
-











+
-
-
+
+
+











+




-
+
-

-
+

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




+
-
-
+
+
+




+
-
-
+
+
+




+
-
-
+
+
+





+







-
+
+


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







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

#include "config.h"

#include <unistd.h>
#include <errno.h>

#include <assert.h>

#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>

#import "OFStreamObserver_kqueue.h"
#import "OFDataArray.h"

#import "OFInitializationFailedException.h"
#import "OFOutOfMemoryException.h"

@interface OFStreamObserver_kqueue (addEventForFileDescriptor)
#define EVENTLIST_SIZE 64
- (void)_addEventForFileDescriptor: (int)fd
			    filter: (int16_t)filter;
@end

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

	@try {
		if ((kernelQueue = kqueue()) == -1)
			@throw [OFInitializationFailedException
			    newWithClass: isa];

		changeList = [[OFDataArray alloc] initWithItemSize:
		[self _addEventForFileDescriptor: cancelFD[0]
					  filter: EVFILT_READ];
		    sizeof(struct kevent)];

		[self _addFileDescriptorForReading: cancelFD[0]];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	close(kernelQueue);
	[changeList release];

	[super dealloc];
}

- (void)_addEventForFileDescriptor: (int)fd
- (void)_addFileDescriptorForReading: (int)fd
			    filter: (int16_t)filter
{
	struct kevent event, result;
	struct kevent event;

	eventList = [self resizeMemory: eventList
			      toNItems: FDs + 1
				ofSize: sizeof(struct kevent)];

	EV_SET(&event, fd, filter, EV_ADD | EV_RECEIPT, 0, 0, 0);

	EV_SET(&event, fd, EVFILT_READ, EV_ADD, 0, 0, 0);
	[changeList addItem: &event];
	if (kevent(kernelQueue, &event, 1, &result, 1, NULL) != 1 ||
	    result.data != 0)
		/* FIXME: Find a better exception */
		@throw [OFInitializationFailedException newWithClass: isa];

	FDs++;
}

- (void)_removeEventForFileDescriptor: (int)fd
			       filter: (int16_t)filter
{
	struct kevent event, result;

	EV_SET(&event, fd, filter, EV_DELETE | EV_RECEIPT, 0, 0, 0);

	if (kevent(kernelQueue, &event, 1, &result, 1, NULL) != 1)
		/* FIXME: Find a better exception */
		@throw [OFInitializationFailedException newWithClass: isa];

	@try {
		eventList = [self resizeMemory: eventList
				      toNItems: FDs - 1
					ofSize: sizeof(struct kevent)];
	} @catch (OFOutOfMemoryException *e) {
		/* We don't care, as we only made it smaller */
		[e release];
	}

	FDs--;
}

- (void)_addFileDescriptorForReading: (int)fd
{
	[self _addEventForFileDescriptor: fd
				  filter: EVFILT_READ];
}

- (void)_addFileDescriptorForWriting: (int)fd
{
	struct kevent event;
	[self _addEventForFileDescriptor: fd
				  filter: EVFILT_WRITE];

	EV_SET(&event, fd, EVFILT_WRITE, EV_ADD, 0, 0, 0);
	[changeList addItem: &event];
}

- (void)_removeFileDescriptorForReading: (int)fd
{
	struct kevent event;
	[self _removeEventForFileDescriptor: fd
				     filter: EVFILT_READ];

	EV_SET(&event, fd, EVFILT_READ, EV_DELETE, 0, 0, 0);
	[changeList addItem: &event];
}

- (void)_removeFileDescriptorForWriting: (int)fd
{
	struct kevent event;
	[self _removeEventForFileDescriptor: fd
				     filter: EVFILT_WRITE];

	EV_SET(&event, fd, EVFILT_WRITE, EV_DELETE, 0, 0, 0);
	[changeList addItem: &event];
}

- (BOOL)observeWithTimeout: (int)timeout
{
	struct timespec timespec = { timeout, 0 };
	struct kevent eventList[EVENTLIST_SIZE];
	int i, events;

	[self _processQueue];

	if ([self _processCache])
		return YES;

	events = kevent(kernelQueue, NULL, 0, eventList, FDs,
	events = kevent(kernelQueue, [changeList cArray],
	    (int)[changeList count], eventList, EVENTLIST_SIZE,
	    (timeout == -1 ? NULL : &timespec));

	if (events == -1)
		/* FIXME: Throw something */;
	if (events == -1) {
		switch (errno) {
		case EINTR:
			return NO;
		case ENOMEM:
			@throw [OFOutOfMemoryException newWithClass: isa];
		default:
			assert(0);
		}
	}

	[changeList removeNItems: [changeList count]];

	if (events == 0)
		return NO;

	for (i = 0; i < events; i++) {
		if (eventList[i].ident == cancelFD[0]) {
			char buffer;

Modified src/exceptions/OFOutOfMemoryException.m from [826b8163be] to [047d11c618].

38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52







-
+







}

- (OFString*)description
{
	if (description != nil)
		return description;

	if (requestedSize)
	if (requestedSize != 0)
		description = [[OFString alloc] initWithFormat:
		    @"Could not allocate %zu bytes in class %@!", requestedSize,
		    inClass];
	else
		description = [[OFString alloc] initWithFormat:
		    @"Could not allocate enough memory in class %@!", inClass];