1 | |
|
|
2 | /* |
1 | /* |
3 | * Copyright 2007 Marc Alexander Lehmann <libev@schmorp.de> |
2 | * Copyright 2007 Marc Alexander Lehmann <libev@schmorp.de> |
4 | * Copyright 2000-2002 Niels Provos <provos@citi.umich.edu> |
3 | * Copyright 2000-2002 Niels Provos <provos@citi.umich.edu> |
5 | * All rights reserved. |
4 | * All rights reserved. |
6 | * |
5 | * |
… | |
… | |
54 | ke->filter = filter; |
53 | ke->filter = filter; |
55 | ke->flags = flags; |
54 | ke->flags = flags; |
56 | ke->fflags = fflags; |
55 | ke->fflags = fflags; |
57 | } |
56 | } |
58 | |
57 | |
|
|
58 | #ifndef NOTE_EOF |
|
|
59 | # define NOTE_EOF 0 |
|
|
60 | #endif |
|
|
61 | |
59 | static void |
62 | static void |
60 | kqueue_modify (int fd, int oev, int nev) |
63 | kqueue_modify (int fd, int oev, int nev) |
61 | { |
64 | { |
62 | if ((oev ^ new) & EV_READ) |
65 | if ((oev ^ nev) & EV_READ) |
63 | { |
66 | { |
64 | if (nev & EV_READ) |
67 | if (nev & EV_READ) |
65 | kqueue_change (fd, EVFILT_READ, EV_ADD, NOTE_EOF); |
68 | kqueue_change (fd, EVFILT_READ, EV_ADD, NOTE_EOF); |
66 | else |
69 | else |
67 | kqueue_change (fd, EVFILT_READ, EV_DELETE, 0); |
70 | kqueue_change (fd, EVFILT_READ, EV_DELETE, 0); |
68 | } |
71 | } |
69 | |
72 | |
70 | if ((oev ^ new) & EV_WRITE) |
73 | if ((oev ^ nev) & EV_WRITE) |
71 | { |
74 | { |
72 | if (nev & EV_WRITE) |
75 | if (nev & EV_WRITE) |
73 | kqueue_change (fd, EVFILT_WRITE, EV_ADD, NOTE_EOF); |
76 | kqueue_change (fd, EVFILT_WRITE, EV_ADD, NOTE_EOF); |
74 | else |
77 | else |
75 | kqueue_change (fd, EVFILT_WRITE, EV_DELETE, 0); |
78 | kqueue_change (fd, EVFILT_WRITE, EV_DELETE, 0); |
… | |
… | |
104 | * should not be returned ever; but FreeBSD does :-\ |
107 | * should not be returned ever; but FreeBSD does :-\ |
105 | * An error is also indicated when a callback deletes |
108 | * An error is also indicated when a callback deletes |
106 | * an event we are still processing. In that case |
109 | * an event we are still processing. In that case |
107 | * the data field is set to ENOENT. |
110 | * the data field is set to ENOENT. |
108 | */ |
111 | */ |
109 | if (events [i].data == EBADF) |
112 | if (kq_events [i].data == EBADF) |
110 | fd_kill (events [i].ident); |
113 | fd_kill (kq_events [i].ident); |
111 | } |
114 | } |
112 | else |
115 | else |
113 | fd_event ( |
116 | fd_event ( |
114 | events [i].ident, |
117 | kq_events [i].ident, |
115 | events [i].filter == EVFILT_READ ? EV_READ |
118 | kq_events [i].filter == EVFILT_READ ? EV_READ |
116 | : events [i].filter == EVFILT_WRITE ? EV_WRITE |
119 | : kq_events [i].filter == EVFILT_WRITE ? EV_WRITE |
117 | : 0 |
120 | : 0 |
118 | ); |
121 | ); |
119 | } |
122 | } |
120 | |
123 | |
121 | if (expect_false (res == kq_eventmax)) |
124 | if (expect_false (res == kq_eventmax)) |
… | |
… | |
125 | kq_events = malloc (sizeof (struct kevent) * kq_eventmax); |
128 | kq_events = malloc (sizeof (struct kevent) * kq_eventmax); |
126 | } |
129 | } |
127 | } |
130 | } |
128 | |
131 | |
129 | static void |
132 | static void |
130 | kqueue_init (struct event_base *base) |
133 | kqueue_init (int flags) |
131 | { |
134 | { |
132 | struct kevent ch, ev; |
135 | struct kevent ch, ev; |
133 | |
136 | |
134 | /* Initalize the kernel queue */ |
137 | /* Initalize the kernel queue */ |
135 | if ((kq_fd = kqueue ()) < 0) |
138 | if ((kq_fd = kqueue ()) < 0) |
… | |
… | |
140 | ch.filter = EVFILT_READ; |
143 | ch.filter = EVFILT_READ; |
141 | ch.flags = EV_ADD; |
144 | ch.flags = EV_ADD; |
142 | |
145 | |
143 | /* |
146 | /* |
144 | * If kqueue works, then kevent will succeed, and it will |
147 | * If kqueue works, then kevent will succeed, and it will |
145 | * stick an error in events[0]. If kqueue is broken, then |
148 | * stick an error in ev. If kqueue is broken, then |
146 | * kevent will fail. |
149 | * kevent will fail. |
147 | */ |
150 | */ |
148 | if (kevent (kq_fd, &ch, 1, &ev, 1, 0) != 1 |
151 | if (kevent (kq_fd, &ch, 1, &ev, 1, 0) != 1 |
149 | || ev.ident != -1 |
152 | || ev.ident != -1 |
150 | || ev.flags != EV_ERROR) |
153 | || ev.flags != EV_ERROR) |