ObjFW  Diff

Differences From Artifact [828093c668]:

To Artifact [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;