1 |
|
/* |
2 |
|
* ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd) |
3 |
|
* |
4 |
< |
* Copyright (c) 2000-2015 ircd-hybrid development team |
4 |
> |
* Copyright (c) 2000-2018 ircd-hybrid development team |
5 |
|
* |
6 |
|
* This program is free software; you can redistribute it and/or modify |
7 |
|
* it under the terms of the GNU General Public License as published by |
34 |
|
|
35 |
|
enum { KE_LENGTH = 128 }; |
36 |
|
|
37 |
< |
static fde_t kqfd; |
37 |
> |
static int kqueue_fd; |
38 |
|
static struct kevent kq_fdlist[KE_LENGTH]; /* kevent buffer */ |
39 |
|
static int kqoff; /* offset into the buffer */ |
40 |
|
|
41 |
|
|
42 |
|
/* |
43 |
< |
* init_netio |
43 |
> |
* comm_select_init |
44 |
|
* |
45 |
|
* This is a needed exported function which will be called to initialise |
46 |
|
* the network loop code. |
47 |
|
*/ |
48 |
|
void |
49 |
< |
init_netio(void) |
49 |
> |
comm_select_init(void) |
50 |
|
{ |
51 |
< |
int fd; |
52 |
< |
|
53 |
< |
if ((fd = kqueue()) < 0) |
51 |
> |
if ((kqueue_fd = kqueue()) < 0) |
52 |
|
{ |
53 |
< |
ilog(LOG_TYPE_IRCD, "init_netio: couldn't open kqueue fd: %s", strerror(errno)); |
53 |
> |
ilog(LOG_TYPE_IRCD, "comm_select_init: couldn't open kqueue fd: %s", |
54 |
> |
strerror(errno)); |
55 |
|
exit(EXIT_FAILURE); /* Whee! */ |
56 |
|
} |
57 |
|
|
58 |
< |
fd_open(&kqfd, fd, 0, "kqueue() file descriptor"); |
58 |
> |
fd_open(kqueue_fd, 0, "kqueue() file descriptor"); |
59 |
|
} |
60 |
|
|
61 |
|
/* |
62 |
|
* Write a single update to the kqueue list. |
63 |
|
*/ |
64 |
|
static void |
65 |
< |
kq_update_events(int fd, int filter, int what) |
65 |
> |
kq_update_events(fde_t *F, int filter, int what) |
66 |
|
{ |
67 |
< |
static struct timespec zero_timespec = {0, 0}; |
67 |
> |
const struct timespec zero_timespec = { .tv_sec = 0, .tv_nsec = 0 }; |
68 |
|
struct kevent *kep = kq_fdlist + kqoff; |
69 |
|
|
70 |
< |
EV_SET(kep, (uintptr_t) fd, (short) filter, what, 0, 0, NULL); |
70 |
> |
EV_SET(kep, (uintptr_t) F->fd, (short) filter, what, 0, 0, F); |
71 |
|
|
72 |
|
if (++kqoff == KE_LENGTH) |
73 |
|
{ |
74 |
|
int i; |
75 |
|
|
76 |
|
for (i = 0; i < kqoff; ++i) |
77 |
< |
kevent(kqfd.fd, &kq_fdlist[i], 1, NULL, 0, &zero_timespec); |
77 |
> |
kevent(kqueue_fd, &kq_fdlist[i], 1, NULL, 0, &zero_timespec); |
78 |
|
kqoff = 0; |
79 |
|
} |
80 |
|
} |
87 |
|
*/ |
88 |
|
void |
89 |
|
comm_setselect(fde_t *F, unsigned int type, void (*handler)(fde_t *, void *), |
90 |
< |
void *client_data, time_t timeout) |
90 |
> |
void *client_data, uintmax_t timeout) |
91 |
|
{ |
92 |
|
int new_events, diff; |
93 |
|
|
116 |
|
diff = new_events ^ F->evcache; |
117 |
|
|
118 |
|
if ((diff & COMM_SELECT_READ)) |
119 |
< |
kq_update_events(F->fd, EVFILT_READ, |
121 |
< |
(new_events & COMM_SELECT_READ) ? EV_ADD : EV_DELETE); |
119 |
> |
kq_update_events(F, EVFILT_READ, (new_events & COMM_SELECT_READ) ? EV_ADD : EV_DELETE); |
120 |
|
if ((diff & COMM_SELECT_WRITE)) |
121 |
< |
kq_update_events(F->fd, EVFILT_WRITE, |
124 |
< |
(new_events & COMM_SELECT_WRITE) ? EV_ADD : EV_DELETE); |
121 |
> |
kq_update_events(F, EVFILT_WRITE, (new_events & COMM_SELECT_WRITE) ? EV_ADD : EV_DELETE); |
122 |
|
|
123 |
|
F->evcache = new_events; |
124 |
|
} |
138 |
|
static struct kevent ke[KE_LENGTH]; |
139 |
|
struct timespec poll_time; |
140 |
|
void (*hdl)(fde_t *, void *); |
144 |
– |
fde_t *F; |
141 |
|
|
142 |
|
/* |
143 |
|
* remember we are doing NANOseconds here, not micro/milli. God knows |
146 |
|
*/ |
147 |
|
poll_time.tv_sec = 0; |
148 |
|
poll_time.tv_nsec = SELECT_DELAY * 1000000; |
149 |
< |
num = kevent(kqfd.fd, kq_fdlist, kqoff, ke, KE_LENGTH, &poll_time); |
149 |
> |
num = kevent(kqueue_fd, kq_fdlist, kqoff, ke, KE_LENGTH, &poll_time); |
150 |
|
kqoff = 0; |
151 |
|
|
152 |
|
set_time(); |
160 |
|
|
161 |
|
for (i = 0; i < num; i++) |
162 |
|
{ |
163 |
< |
F = lookup_fd(ke[i].ident); |
164 |
< |
if (F == NULL || !F->flags.open || (ke[i].flags & EV_ERROR)) |
163 |
> |
fde_t *F = ke[i].udata; |
164 |
> |
|
165 |
> |
if (F->flags.open == 0 || (ke[i].flags & EV_ERROR)) |
166 |
|
continue; |
167 |
|
|
168 |
|
if (ke[i].filter == EVFILT_READ) |
171 |
|
{ |
172 |
|
F->read_handler = NULL; |
173 |
|
hdl(F, F->read_data); |
174 |
< |
if (!F->flags.open) |
174 |
> |
|
175 |
> |
if (F->flags.open == 0) |
176 |
|
continue; |
177 |
|
} |
178 |
|
} |
183 |
|
{ |
184 |
|
F->write_handler = NULL; |
185 |
|
hdl(F, F->write_data); |
186 |
< |
if (!F->flags.open) |
186 |
> |
|
187 |
> |
if (F->flags.open == 0) |
188 |
|
continue; |
189 |
|
} |
190 |
|
} |