1/* 2 * Copyright (c) 2009 Mark Heily <mark@heily.com> 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17#include <stdlib.h> 18#include <port.h> 19#include <poll.h> 20 21#include "sys/event.h" 22#include "private.h" 23 24const struct filter evfilt_vnode = EVFILT_NOTIMPL; 25const struct filter evfilt_proc = EVFILT_NOTIMPL; 26 27/* Dump a poll(2) events bitmask */ 28static char * 29poll_events_dump(short events) 30{ 31 static char __thread buf[512]; 32 33#define _PL_DUMP(attrib) \ 34 if (events == attrib) \ 35 strcat(&buf[0], " "#attrib); 36 37 snprintf(&buf[0], 512, "events = %hd 0x%o (", events, events); 38 _PL_DUMP(POLLIN); 39 _PL_DUMP(POLLPRI); 40 _PL_DUMP(POLLOUT); 41 _PL_DUMP(POLLRDNORM); 42 _PL_DUMP(POLLRDBAND); 43 _PL_DUMP(POLLWRBAND); 44 _PL_DUMP(POLLERR); 45 _PL_DUMP(POLLHUP); 46 _PL_DUMP(POLLNVAL); 47 strcat(&buf[0], ")"); 48 49 return (&buf[0]); 50 51#undef _PL_DUMP 52} 53 54static char * 55port_event_dump(port_event_t *evt) 56{ 57 static char __thread buf[512]; 58 59 if (evt == NULL) 60 return "(null)"; 61 62#define PE_DUMP(attrib) \ 63 if (evt->portev_source == attrib) \ 64 strcat(&buf[0], #attrib); 65 66 snprintf(&buf[0], 512, 67 " { object = %u, user = %p, %s, source = %d (", 68 (unsigned int) evt->portev_object, 69 evt->portev_user, 70 poll_events_dump(evt->portev_events), 71 evt->portev_source); 72 PE_DUMP(PORT_SOURCE_AIO); 73 PE_DUMP(PORT_SOURCE_FD); 74 PE_DUMP(PORT_SOURCE_TIMER); 75 PE_DUMP(PORT_SOURCE_USER); 76 PE_DUMP(PORT_SOURCE_ALERT); 77 strcat(&buf[0], ") }\n"); 78 79 return (&buf[0]); 80#undef PE_DUMP 81} 82 83int 84kevent_wait(struct kqueue *kq, const struct timespec *timeout) 85{ 86 port_event_t *pe = (port_event_t *) pthread_getspecific(kq->kq_port_event); 87 88 int rv; 89 uint_t nget = 1; 90 91 reset_errno(); 92 dbg_printf("waiting for events (timeout=%p)", timeout); 93 rv = port_getn(kq->kq_port, pe, 1, &nget, (struct timespec *) timeout); 94 dbg_printf("rv=%d errno=%d (%s) nget=%d", 95 rv, errno, strerror(errno), nget); 96 if (rv < 0) { 97 if (errno == ETIME) { 98 dbg_puts("no events within the given timeout"); 99 return (0); 100 } 101 if (errno == EINTR) { 102 dbg_puts("signal caught"); 103 return (-1); 104 } 105 dbg_perror("port_get(2)"); 106 return (-1); 107 } 108 109 return (nget); 110} 111 112int 113kevent_copyout(struct kqueue *kq, int nready, 114 struct kevent *eventlist, int nevents) 115{ 116 port_event_t *pe = (port_event_t *) pthread_getspecific(kq->kq_port_event); 117 struct filter *filt; 118 int rv; 119 120 dbg_printf("%s", port_event_dump(pe)); 121 switch (pe->portev_source) { 122 case PORT_SOURCE_FD: 123 filt = pe->portev_user; 124 rv = filt->kf_copyout(filt, eventlist, nevents); 125 break; 126 127 case PORT_SOURCE_TIMER: 128 filter_lookup(&filt, kq, EVFILT_TIMER); 129 rv = filt->kf_copyout(filt, eventlist, nevents); 130 break; 131 132 case PORT_SOURCE_USER: 133 switch (pe->portev_events) { 134 case X_PORT_SOURCE_SIGNAL: 135 filter_lookup(&filt, kq, EVFILT_SIGNAL); 136 rv = filt->kf_copyout(filt, eventlist, nevents); 137 break; 138 case X_PORT_SOURCE_USER: 139 filter_lookup(&filt, kq, EVFILT_USER); 140 rv = filt->kf_copyout(filt, eventlist, nevents); 141 break; 142 default: 143 dbg_puts("unsupported portev_events"); 144 abort(); 145 } 146 break; 147 148 default: 149 dbg_puts("unsupported source"); 150 abort(); 151 } 152 if (rv < 0) { 153 dbg_puts("kevent_copyout failed"); 154 return (-1); 155 } 156 157 return (1); 158} 159