parlib: Trim some header includes
[akaros.git] / user / iplib / epoll.c
1 /* Copyright (c) 2015 Google Inc.
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * Epoll, built on FD taps, CEQs, and blocking uthreads on event queues.
6  *
7  * TODO: There are a few incompatibilities with Linux's epoll, some of which are
8  * artifacts of the implementation, and other issues:
9  *      - you can't epoll on an epoll fd (or any user fd).  you can only epoll on a
10  *      kernel FD that accepts your FD taps.
11  *      - there's no EPOLLONESHOT or level-triggered support.
12  *      - you can only tap one FD at a time, so you can't add the same FD to
13  *      multiple epoll sets.
14  *      - closing the epoll is a little dangerous, if there are outstanding INDIR
15  *      events.  this will only pop up if you're yielding cores, maybe getting
16  *      preempted, and are unlucky.
17  *      - epoll_create1 does not support CLOEXEC.  That'd need some work in glibc's
18  *      exec and flags in struct user_fd.
19  *      - EPOLL_CTL_MOD is just a DEL then an ADD.  There might be races associated
20  *      with that.
21  *      - epoll_pwait is probably racy.
22  *      - You can't dup an epoll fd (same as other user FDs).
23  *      - If you add a BSD socket FD to an epoll set, you'll get taps on both the
24  *      data FD and the listen FD.
25  *      - If you add the same BSD socket listener to multiple epoll sets, you will
26  *      likely fail.  This is in addition to being able to tap only one FD at a
27  *      time.
28  * */
29
30 #include <sys/epoll.h>
31 #include <parlib/parlib.h>
32 #include <parlib/event.h>
33 #include <parlib/ceq.h>
34 #include <parlib/uthread.h>
35 #include <parlib/timing.h>
36 #include <parlib/slab.h>
37 #include <parlib/assert.h>
38 #include <sys/user_fd.h>
39 #include <sys/close_cb.h>
40 #include <stdio.h>
41 #include <errno.h>
42 #include <unistd.h>
43 #include <malloc.h>
44 #include <sys/queue.h>
45 #include <sys/plan9_helpers.h>
46 #include <ros/fs.h>
47
48 /* Sanity check, so we can ID our own FDs */
49 #define EPOLL_UFD_MAGIC                 0xe9011
50
51 /* Each waiter that uses a timeout will have its own structure for dealing with
52  * its timeout.
53  *
54  * TODO: (RCU/SLAB) it's not safe to reap the objects, until we sort out
55  * INDIRs and RCU-style grace periods.  Not a big deal, since the number of
56  * these is the number of threads that concurrently do epoll timeouts. */
57 struct ep_alarm {
58         struct event_queue                      *alarm_evq;
59         struct syscall                          sysc;
60 };
61
62 static struct kmem_cache *ep_alarms_cache;
63
64 struct epoll_ctlr {
65         TAILQ_ENTRY(epoll_ctlr)         link;
66         struct event_queue                      *ceq_evq;
67         uth_mutex_t                                     *mtx;
68         struct user_fd                          ufd;
69 };
70
71 TAILQ_HEAD(epoll_ctlrs, epoll_ctlr);
72 static struct epoll_ctlrs all_ctlrs = TAILQ_HEAD_INITIALIZER(all_ctlrs);
73 static uth_mutex_t *ctlrs_mtx;
74
75 /* There's some bookkeeping we need to maintain on every FD.  Right now, the FD
76  * is the index into the CEQ event array, so we can just hook this into the user
77  * data blob in the ceq_event.
78  *
79  * If we ever do not maintain a 1:1 mapping from FDs to CEQ IDs, we can use this
80  * to track the CEQ ID and FD. */
81 struct ep_fd_data {
82         struct epoll_event                      ep_event;
83         int                                                     fd;
84         int                                                     filter;
85 };
86
87 /* Converts epoll events to FD taps. */
88 static int ep_events_to_taps(uint32_t ep_ev)
89 {
90         int taps = 0;
91         if (ep_ev & EPOLLIN)
92                 taps |= FDTAP_FILT_READABLE;
93         if (ep_ev & EPOLLOUT)
94                 taps |= FDTAP_FILT_WRITABLE;
95         if (ep_ev & EPOLLRDHUP)
96                 taps |= FDTAP_FILT_RDHUP;
97         if (ep_ev & EPOLLPRI)
98                 taps |= FDTAP_FILT_PRIORITY;
99         if (ep_ev & EPOLLERR)
100                 taps |= FDTAP_FILT_ERROR;
101         if (ep_ev & EPOLLHUP)
102                 taps |= FDTAP_FILT_HANGUP;
103         return taps;
104 }
105
106 /* Converts corresponding FD Taps to epoll events.  There are other taps that do
107  * not make sense for epoll. */
108 static uint32_t taps_to_ep_events(int taps)
109 {
110         uint32_t ep_ev = 0;
111         if (taps & FDTAP_FILT_READABLE)
112                 ep_ev |= EPOLLIN;
113         if (taps & FDTAP_FILT_WRITABLE)
114                 ep_ev |= EPOLLOUT;
115         if (taps & FDTAP_FILT_RDHUP)
116                 ep_ev |= EPOLLRDHUP;
117         if (taps & FDTAP_FILT_PRIORITY)
118                 ep_ev |= EPOLLPRI;
119         if (taps & FDTAP_FILT_ERROR)
120                 ep_ev |= EPOLLERR;
121         if (taps & FDTAP_FILT_HANGUP)
122                 ep_ev |= EPOLLHUP;
123         return ep_ev;
124 }
125
126 static unsigned int ep_get_ceq_max_ever(struct epoll_ctlr *ep)
127 {
128         return atomic_read(&ep->ceq_evq->ev_mbox->ceq.max_event_ever);
129 }
130
131 static struct ceq_event *ep_get_ceq_ev(struct epoll_ctlr *ep, size_t idx)
132 {
133         if (ep->ceq_evq->ev_mbox->ceq.nr_events <= idx)
134                 return 0;
135         return &ep->ceq_evq->ev_mbox->ceq.events[idx];
136 }
137
138 static struct epoll_ctlr *fd_to_cltr(int fd)
139 {
140         struct user_fd *ufd = ufd_lookup(fd);
141         if (!ufd)
142                 return 0;
143         if (ufd->magic != EPOLL_UFD_MAGIC) {
144                 errno = EBADF;
145                 return 0;
146         }
147         return container_of(ufd, struct epoll_ctlr, ufd);
148 }
149
150 /* Event queue helpers: */
151 static struct event_queue *ep_get_ceq_evq(unsigned int ceq_ring_sz)
152 {
153         struct event_queue *ceq_evq = get_eventq_raw();
154         ceq_evq->ev_mbox->type = EV_MBOX_CEQ;
155         ceq_init(&ceq_evq->ev_mbox->ceq, CEQ_OR, NR_FILE_DESC_MAX, ceq_ring_sz);
156         ceq_evq->ev_flags = EVENT_INDIR | EVENT_SPAM_INDIR | EVENT_WAKEUP;
157         evq_attach_wakeup_ctlr(ceq_evq);
158         return ceq_evq;
159 }
160
161 static struct event_queue *ep_get_alarm_evq(void)
162 {
163         /* Don't care about the actual message, just using it for a wakeup */
164         struct event_queue *alarm_evq = get_eventq(EV_MBOX_BITMAP);
165         alarm_evq->ev_flags = EVENT_INDIR | EVENT_SPAM_INDIR | EVENT_WAKEUP;
166         evq_attach_wakeup_ctlr(alarm_evq);
167         return alarm_evq;
168 }
169
170 /* Once we've closed our sources of events, we can try to clean up the event
171  * queues.  These are actually dangerous, since there could be INDIRs floating
172  * around for these evqs still, which are basically pointers.  We'll need to run
173  * some sort of user deferred destruction. (TODO). */
174 static void ep_put_ceq_evq(struct event_queue *ceq_evq)
175 {
176 #if 0 /* TODO: EVQ/INDIR Cleanup */
177         ceq_cleanup(&ceq_evq->ev_mbox->ceq);
178         evq_remove_wakeup_ctlr(ceq_evq);
179         put_eventq_raw(ceq_evq);
180 #endif
181 }
182
183 static void ep_put_alarm_evq(struct event_queue *alarm_evq)
184 {
185 #if 0 /* TODO: EVQ/INDIR Cleanup */
186         evq_remove_wakeup_ctlr(alarm_evq);
187         put_eventq(alarm_evq);
188 #endif
189 }
190
191 static void epoll_close(struct user_fd *ufd)
192 {
193         struct epoll_ctlr *ep = container_of(ufd, struct epoll_ctlr, ufd);
194         struct fd_tap_req *tap_reqs, *tap_req_i;
195         struct ceq_event *ceq_ev_i;
196         struct ep_fd_data *ep_fd_i;
197         int nr_tap_req = 0;
198         int nr_done = 0;
199         unsigned int max_ceq_events = ep_get_ceq_max_ever(ep);
200
201         tap_reqs = malloc(sizeof(struct fd_tap_req) * max_ceq_events);
202         memset(tap_reqs, 0, sizeof(struct fd_tap_req) * max_ceq_events);
203         /* Slightly painful, O(n) with no escape hatch */
204         for (int i = 0; i < max_ceq_events; i++) {
205                 ceq_ev_i = ep_get_ceq_ev(ep, i);
206                 /* CEQ should have been big enough for our size */
207                 assert(ceq_ev_i);
208                 ep_fd_i = (struct ep_fd_data*)ceq_ev_i->user_data;
209                 if (!ep_fd_i)
210                         continue;
211                 tap_req_i = &tap_reqs[nr_tap_req++];
212                 tap_req_i->fd = i;
213                 tap_req_i->cmd = FDTAP_CMD_REM;
214                 free(ep_fd_i);
215         }
216         /* Requests could fail if the tapped files are already closed.  We need to
217          * skip the failed one (the +1) and untap the rest. */
218         do {
219                 nr_done += sys_tap_fds(tap_reqs + nr_done, nr_tap_req - nr_done);
220                 nr_done += 1;   /* nr_done could be more than nr_tap_req now */
221         } while (nr_done < nr_tap_req);
222         free(tap_reqs);
223         ep_put_ceq_evq(ep->ceq_evq);
224         uth_mutex_lock(ctlrs_mtx);
225         TAILQ_REMOVE(&all_ctlrs, ep, link);
226         uth_mutex_unlock(ctlrs_mtx);
227         uth_mutex_free(ep->mtx);
228         free(ep);
229 }
230
231 static int init_ep_ctlr(struct epoll_ctlr *ep, int size)
232 {
233         if (size == 1)
234                 size = 128;
235         ep->mtx = uth_mutex_alloc();
236         ep->ufd.magic = EPOLL_UFD_MAGIC;
237         ep->ufd.close = epoll_close;
238         /* Size is a hint for the CEQ concurrency.  We can actually handle as many
239          * kernel FDs as is possible. */
240         ep->ceq_evq = ep_get_ceq_evq(ROUNDUPPWR2(size));
241         return 0;
242 }
243
244 static void epoll_fd_closed(int fd)
245 {
246         struct epoll_ctlr *ep;
247
248         /* Lockless peek, avoid locking for every close() */
249         if (TAILQ_EMPTY(&all_ctlrs))
250                 return;
251         uth_mutex_lock(ctlrs_mtx);
252         TAILQ_FOREACH(ep, &all_ctlrs, link)
253                 epoll_ctl(ep->ufd.fd, EPOLL_CTL_DEL, fd, 0);
254         uth_mutex_unlock(ctlrs_mtx);
255 }
256
257 static void ep_alarm_ctor(void *obj, size_t unused)
258 {
259         struct ep_alarm *ep_a = (struct ep_alarm*)obj;
260
261         ep_a->alarm_evq = ep_get_alarm_evq();
262 }
263
264 static void ep_alarm_dtor(void *obj, size_t unused)
265 {
266         struct ep_alarm *ep_a = (struct ep_alarm*)obj;
267
268         /* TODO: (RCU/SLAB).  Somehow the slab allocator is trying to reap our
269          * objects.  Note that when we update userspace to use magazines, the dtor
270          * will fire earlier (when the object is given to the slab layer).  We'll
271          * need to be careful about the final freeing of the ev_q. */
272         panic("Epoll alarms should never be destroyed!");
273         ep_put_alarm_evq(ep_a->alarm_evq);
274 }
275
276 static void epoll_init(void *arg)
277 {
278         static struct close_cb epoll_close_cb = {.func = epoll_fd_closed};
279
280         register_close_cb(&epoll_close_cb);
281         ctlrs_mtx = uth_mutex_alloc();
282         ep_alarms_cache = kmem_cache_create("epoll alarms",
283                                             sizeof(struct ep_alarm),
284                                             __alignof__(sizeof(struct ep_alarm)), 0,
285                                             ep_alarm_ctor, ep_alarm_dtor);
286         assert(ep_alarms_cache);
287 }
288
289 int epoll_create(int size)
290 {
291         int fd;
292         struct epoll_ctlr *ep;
293         static parlib_once_t once = PARLIB_ONCE_INIT;
294
295         parlib_run_once(&once, epoll_init, NULL);
296         /* good thing the arg is a signed int... */
297         if (size < 0) {
298                 errno = EINVAL;
299                 return -1;
300         }
301         ep = malloc(sizeof(struct epoll_ctlr));
302         memset(ep, 0, sizeof(struct epoll_ctlr));
303         if (init_ep_ctlr(ep, size)) {
304                 free(ep);
305                 return -1;
306         }
307         fd = ufd_get_fd(&ep->ufd);
308         if (fd < 0)
309                 free(ep);
310         uth_mutex_lock(ctlrs_mtx);
311         TAILQ_INSERT_TAIL(&all_ctlrs, ep, link);
312         uth_mutex_unlock(ctlrs_mtx);
313         return fd;
314 }
315
316 int epoll_create1(int flags)
317 {
318         /* TODO: we're supposed to support CLOEXEC.  Our FD is a user_fd, so that'd
319          * require some support in glibc's exec to close our epoll ctlr. */
320         return epoll_create(1);
321 }
322
323 /* Linux's epoll will check for events, even if edge-triggered, during
324  * additions (and probably modifications) to the epoll set.  It's a questionable
325  * policy, since it can hide user bugs.
326  *
327  * We can do the same, though only for EPOLLIN and EPOLLOUT for FDs that can
328  * report their status via stat.  (same as select()).
329  *
330  * Note that this could result in spurious events, which should be fine. */
331 static void fire_existing_events(int fd, int ep_events,
332                                  struct event_queue *ev_q)
333 {
334         struct stat stat_buf[1];
335         struct event_msg ev_msg[1];
336         int ret;
337         int synth_ep_events = 0;
338
339         ret = fstat(fd, stat_buf);
340         assert(!ret);
341         if ((ep_events & EPOLLIN) && S_READABLE(stat_buf->st_mode))
342                 synth_ep_events |= EPOLLIN;
343         if ((ep_events & EPOLLOUT) && S_WRITABLE(stat_buf->st_mode))
344                 synth_ep_events |= EPOLLOUT;
345         if (synth_ep_events) {
346                 ev_msg->ev_type = fd;
347                 ev_msg->ev_arg2 = ep_events_to_taps(synth_ep_events);
348                 ev_msg->ev_arg3 = 0; /* tap->data is unused for epoll. */
349                 sys_send_event(ev_q, ev_msg, vcore_id());
350         }
351 }
352
353 static int __epoll_ctl_add(struct epoll_ctlr *ep, int fd,
354                            struct epoll_event *event)
355 {
356         struct ceq_event *ceq_ev;
357         struct ep_fd_data *ep_fd;
358         struct fd_tap_req tap_req = {0};
359         int ret, filter, sock_listen_fd;
360         struct epoll_event listen_event;
361
362         /* Only support ET.  Also, we just ignore EPOLLONESHOT.  That might work,
363          * logically, just with spurious events firing. */
364         if (!(event->events & EPOLLET)) {
365                 errno = EPERM;
366                 werrstr("Epoll level-triggered not supported");
367                 return -1;
368         }
369         if (event->events & EPOLLONESHOT) {
370                 errno = EPERM;
371                 werrstr("Epoll one-shot not supported");
372                 return -1;
373         }
374         /* The sockets-to-plan9 networking shims are a bit inconvenient.  The user
375          * asked us to epoll on an FD, but that FD is actually a Qdata FD.  We might
376          * need to actually epoll on the listen_fd.  Further, we don't know yet
377          * whether or not they want the listen FD.  They could epoll on the socket,
378          * then listen later and want to wake up on the listen.
379          *
380          * So in the case we have a socket FD, we'll actually open the listen FD
381          * regardless (glibc handles this), and we'll epoll on both FDs.
382          * Technically, either FD could fire and they'd get an epoll event for it,
383          * but I think socket users will use only listen or data.
384          *
385          * As far as tracking the FD goes for epoll_wait() reporting, if the app
386          * wants to track the FD they think we are using, then they already passed
387          * that in event->data. */
388         sock_listen_fd = _sock_lookup_listen_fd(fd);
389         if (sock_listen_fd >= 0) {
390                 listen_event.events = EPOLLET | EPOLLIN | EPOLLHUP;
391                 listen_event.data = event->data;
392                 ret = __epoll_ctl_add(ep, sock_listen_fd, &listen_event);
393                 if (ret < 0)
394                         return ret;
395         }
396         ceq_ev = ep_get_ceq_ev(ep, fd);
397         if (!ceq_ev) {
398                 errno = ENOMEM;
399                 werrstr("Epoll set cannot grow yet!");
400                 return -1;
401         }
402         ep_fd = (struct ep_fd_data*)ceq_ev->user_data;
403         if (ep_fd) {
404                 errno = EEXIST;
405                 return -1;
406         }
407         tap_req.fd = fd;
408         tap_req.cmd = FDTAP_CMD_ADD;
409         /* EPOLLHUP is implicitly set for all epolls. */
410         filter = ep_events_to_taps(event->events | EPOLLHUP);
411         tap_req.filter = filter;
412         tap_req.ev_q = ep->ceq_evq;
413         tap_req.ev_id = fd;     /* using FD as the CEQ ID */
414         ret = sys_tap_fds(&tap_req, 1);
415         if (ret != 1)
416                 return -1;
417         ep_fd = malloc(sizeof(struct ep_fd_data));
418         ep_fd->fd = fd;
419         ep_fd->filter = filter;
420         ep_fd->ep_event = *event;
421         ep_fd->ep_event.events |= EPOLLHUP;
422         ceq_ev->user_data = (uint64_t)ep_fd;
423         fire_existing_events(fd, ep_fd->ep_event.events, ep->ceq_evq);
424         return 0;
425 }
426
427 static int __epoll_ctl_del(struct epoll_ctlr *ep, int fd,
428                            struct epoll_event *event)
429 {
430         struct ceq_event *ceq_ev;
431         struct ep_fd_data *ep_fd;
432         struct fd_tap_req tap_req = {0};
433         int ret, sock_listen_fd;
434
435         /* If we were dealing with a socket shim FD, we tapped both the listen and
436          * the data file and need to untap both of them. */
437         sock_listen_fd = _sock_lookup_listen_fd(fd);
438         if (sock_listen_fd >= 0) {
439                 /* It's possible to fail here.  Even though we tapped it already, if the
440                  * deletion was triggered from close callbacks, it's possible for the
441                  * sock_listen_fd to be closed first, which would have triggered an
442                  * epoll_ctl_del.  When we get around to closing the Rock FD, the listen
443                  * FD was already closed. */
444                 __epoll_ctl_del(ep, sock_listen_fd, event);
445         }
446         ceq_ev = ep_get_ceq_ev(ep, fd);
447         if (!ceq_ev) {
448                 errno = ENOENT;
449                 return -1;
450         }
451         ep_fd = (struct ep_fd_data*)ceq_ev->user_data;
452         if (!ep_fd) {
453                 errno = ENOENT;
454                 return -1;
455         }
456         assert(ep_fd->fd == fd);
457         tap_req.fd = fd;
458         tap_req.cmd = FDTAP_CMD_REM;
459         /* ignoring the return value; we could have failed to remove it if the FD
460          * has already closed and the kernel removed the tap. */
461         sys_tap_fds(&tap_req, 1);
462         ceq_ev->user_data = 0;
463         free(ep_fd);
464         return 0;
465 }
466
467 int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
468 {
469         int ret;
470         struct epoll_ctlr *ep = fd_to_cltr(epfd);
471         if (!ep) {
472                 errno = EBADF;/* or EINVAL */
473                 return -1;
474         }
475         if (fd >= USER_FD_BASE) {
476                 errno = EINVAL;
477                 werrstr("Epoll can't track User FDs");
478                 return -1;
479         }
480         uth_mutex_lock(ep->mtx);
481         switch (op) {
482                 case (EPOLL_CTL_MOD):
483                         /* In lieu of a proper MOD, just remove and readd.  The errors might
484                          * not work out well, and there could be a missed event in the
485                          * middle.  Not sure what the guarantees are, but we can fake a
486                          * poke. (TODO). */
487                         ret = __epoll_ctl_del(ep, fd, 0);
488                         if (ret)
489                                 break;
490                         ret = __epoll_ctl_add(ep, fd, event);
491                         break;
492                 case (EPOLL_CTL_ADD):
493                         ret = __epoll_ctl_add(ep, fd, event);
494                         break;
495                 case (EPOLL_CTL_DEL):
496                         ret = __epoll_ctl_del(ep, fd, event);
497                         break;
498                 default:
499                         errno = EINVAL;
500                         ret = -1;
501         }
502         uth_mutex_unlock(ep->mtx);
503         return ret;
504 }
505
506 static bool get_ep_event_from_msg(struct epoll_ctlr *ep, struct event_msg *msg,
507                                   struct epoll_event *ep_ev)
508 {
509         struct ceq_event *ceq_ev;
510         struct ep_fd_data *ep_fd;
511
512         ceq_ev = ep_get_ceq_ev(ep, msg->ev_type);
513         /* should never get a tap FD > size of the epoll set */
514         assert(ceq_ev);
515         ep_fd = (struct ep_fd_data*)ceq_ev->user_data;
516         if (!ep_fd) {
517                 /* it's possible the FD was unregistered and this was an old
518                  * event sent to this epoll set. */
519                 return FALSE;
520         }
521         ep_ev->data = ep_fd->ep_event.data;
522         /* The events field was initialized to 0 in epoll_wait() */
523         ep_ev->events |= taps_to_ep_events(msg->ev_arg2);
524         return TRUE;
525 }
526
527 /* Helper: extracts as many epoll_events as possible from the ep. */
528 static int __epoll_wait_poll(struct epoll_ctlr *ep, struct epoll_event *events,
529                              int maxevents)
530 {
531         struct event_msg msg = {0};
532         int nr_ret = 0;
533
534         if (maxevents <= 0)
535                 return 0;
536         /* Locking to protect get_ep_event_from_msg, specifically that the ep_fd
537          * stored at ceq_ev->user_data does not get concurrently removed and
538          * freed. */
539         uth_mutex_lock(ep->mtx);
540         for (int i = 0; i < maxevents; i++) {
541 retry:
542                 if (!uth_check_evqs(&msg, NULL, 1, ep->ceq_evq))
543                         break;
544                 if (!get_ep_event_from_msg(ep, &msg, &events[i]))
545                         goto retry;
546                 nr_ret++;
547         }
548         uth_mutex_unlock(ep->mtx);
549         return nr_ret;
550 }
551
552 /* We should be able to have multiple waiters.  ep shouldn't be closed or
553  * anything, since we have the FD (that'd be bad programming on the user's
554  * behalf).  We could have concurrent ADD/MOD/DEL operations (which lock). */
555 static int __epoll_wait(struct epoll_ctlr *ep, struct epoll_event *events,
556                         int maxevents, int timeout)
557 {
558         struct event_msg msg = {0};
559         struct event_msg dummy_msg;
560         struct event_queue *which_evq;
561         struct ep_alarm *ep_a;
562         int nr_ret;
563
564         nr_ret = __epoll_wait_poll(ep, events, maxevents);
565         if (nr_ret)
566                 return nr_ret;
567         if (timeout == 0)
568                 return 0;
569         /* From here on down, we're going to block until there is some activity */
570         if (timeout != -1) {
571                 ep_a = kmem_cache_alloc(ep_alarms_cache, 0);
572                 assert(ep_a);
573                 syscall_async_evq(&ep_a->sysc, ep_a->alarm_evq, SYS_block,
574                                   timeout * 1000);
575                 uth_blockon_evqs(&msg, &which_evq, 2, ep->ceq_evq, ep_a->alarm_evq);
576                 if (which_evq == ep_a->alarm_evq) {
577                         kmem_cache_free(ep_alarms_cache, ep_a);
578                         return 0;
579                 }
580                 /* The alarm sysc may or may not have finished yet.  This will force it
581                  * to *start* to finish iff it is still a submitted syscall. */
582                 sys_abort_sysc(&ep_a->sysc);
583                 /* But we still need to wait until the syscall completed.  Need a
584                  * dummy msg, since we don't want to clobber the real msg. */
585                 uth_blockon_evqs(&dummy_msg, 0, 1, ep_a->alarm_evq);
586                 kmem_cache_free(ep_alarms_cache, ep_a);
587         } else {
588                 uth_blockon_evqs(&msg, &which_evq, 1, ep->ceq_evq);
589         }
590         uth_mutex_lock(ep->mtx);
591         if (get_ep_event_from_msg(ep, &msg, &events[0]))
592                 nr_ret = 1;
593         uth_mutex_unlock(ep->mtx);
594         /* We had to extract one message already as part of the blocking process.
595          * We might be able to get more. */
596         nr_ret += __epoll_wait_poll(ep, events + nr_ret, maxevents - nr_ret);
597         /* This is a little nasty and hopefully a rare race.  We still might not
598          * have a ret, but we expected to block until we had something.  We didn't
599          * time out yet, but we spuriously woke up.  We need to try again (ideally,
600          * we'd subtract the time left from the original timeout). */
601         if (!nr_ret)
602                 return __epoll_wait(ep, events, maxevents, timeout);
603         return nr_ret;
604 }
605
606 int epoll_wait(int epfd, struct epoll_event *events, int maxevents,
607                int timeout)
608 {
609         struct epoll_ctlr *ep = fd_to_cltr(epfd);
610
611         if (!ep) {
612                 errno = EBADF;/* or EINVAL */
613                 return -1;
614         }
615         if (maxevents <= 0) {
616                 errno = EINVAL;
617                 return -1;
618         }
619         for (int i = 0; i < maxevents; i++)
620                 events[i].events = 0;
621         return __epoll_wait(ep, events, maxevents, timeout);
622 }
623
624 int epoll_pwait(int epfd, struct epoll_event *events, int maxevents,
625                 int timeout, const sigset_t *sigmask)
626 {
627         int ready;
628         sigset_t origmask;
629         /* TODO: this is probably racy */
630         sigprocmask(SIG_SETMASK, sigmask, &origmask);
631         ready = epoll_wait(epfd, events, maxevents, timeout);
632         sigprocmask(SIG_SETMASK, &origmask, NULL);
633         return ready;
634 }