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
 *
 * \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)_processQueue;
- (BOOL)_processCache;
/// \endcond
@end

@interface OFObject (OFStreamObserverDelegate) <OFStreamObserverDelegate>
@end







>
>
>
>







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
 * 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"



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







>
>




<
|


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;

	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
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#include <unistd.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)
- (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];


		[self _addEventForFileDescriptor: cancelFD[0]
					  filter: EVFILT_READ];

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

	return self;
}

- (void)dealloc
{
	close(kernelQueue);


	[super dealloc];
}

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

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

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

	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
{

	[self _addEventForFileDescriptor: fd
				  filter: EVFILT_WRITE];

}

- (void)_removeFileDescriptorForReading: (int)fd
{

	[self _removeEventForFileDescriptor: fd
				     filter: EVFILT_READ];

}

- (void)_removeFileDescriptorForWriting: (int)fd
{

	[self _removeEventForFileDescriptor: fd
				     filter: EVFILT_WRITE];

}

- (BOOL)observeWithTimeout: (int)timeout
{
	struct timespec timespec = { timeout, 0 };

	int i, events;

	[self _processQueue];

	if ([self _processCache])
		return YES;

	events = kevent(kernelQueue, NULL, 0, eventList, FDs,

	    (timeout == -1 ? NULL : &timespec));

	if (events == -1)









		/* FIXME: Throw something */;


	if (events == 0)
		return NO;

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








>













|
<
<
<











>
|
|
>











>




|
<

|

<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




>
|
|
>




>
|
|
>




>
|
|
>





>







|
>


|
>
>
>
>
>
>
>
>
>
|
>
>







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"

#define EVENTLIST_SIZE 64




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

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

		changeList = [[OFDataArray alloc] initWithItemSize:
		    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)_addFileDescriptorForReading: (int)fd

{
	struct kevent event;





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



































}

- (void)_addFileDescriptorForWriting: (int)fd
{
	struct kevent event;

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

- (void)_removeFileDescriptorForReading: (int)fd
{
	struct kevent event;

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

- (void)_removeFileDescriptorForWriting: (int)fd
{
	struct kevent event;

	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, [changeList cArray],
	    (int)[changeList count], eventList, EVENTLIST_SIZE,
	    (timeout == -1 ? NULL : &timespec));

	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
}

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

	if (requestedSize)
		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];








|







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

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

	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];