1 #include <sys/param.h> 2 #include <sys/limits.h> 3 #include <sys/uio.h> 4 #include <sys/proc.h> 5 #include <sys/syscallsubr.h> 6 #include <sys/module.h> 7 #include <sys/param.h> 8 #include <sys/malloc.h> 9 #include <sys/socketvar.h> 10 #include <sys/event.h> 11 #include <sys/kernel.h> 12 #include <sys/refcount.h> 13 #include <sys/sysctl.h> 14 #include <sys/pcpu.h> 15 #include <sys/select.h> 16 #include <sys/poll.h> 17 #include <sys/event.h> 18 #include <sys/file.h> 19 #include <netinet/in.h> 20 #include <netinet/tcp.h> 21 #include <sys/ttycom.h> 22 #include <sys/filio.h> 23 #include <sys/sysproto.h> 24 #include <sys/fcntl.h> 25 #include <machine/stdarg.h> 26 27 #include "ff_api.h" 28 #include "ff_epoll.h" 29 #include "ff_errno.h" 30 #include "ff_host_interface.h" 31 32 33 34 int 35 ff_epoll_create(int size __attribute__((__unused__))) 36 { 37 return ff_kqueue(); 38 } 39 40 41 int 42 ff_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) 43 { 44 if (!event && op != EPOLL_CTL_DEL) { 45 ff_os_errno(ff_EINVAL); 46 return -1; 47 } 48 49 struct kevent kev[3]; 50 if (op == EPOLL_CTL_ADD){ 51 EV_SET(&kev[0], fd, EVFILT_READ, 52 EV_ADD | (event->events & EPOLLIN ? 0 : EV_DISABLE), 0, 0, NULL); 53 EV_SET(&kev[1], fd, EVFILT_WRITE, 54 EV_ADD | (event->events & EPOLLOUT ? 0 : EV_DISABLE), 0, 0, NULL); 55 EV_SET(&kev[2], fd, EVFILT_USER, EV_ADD, 56 event->events & EPOLLRDHUP ? 1 : 0, 0, NULL); 57 } else if (op == EPOLL_CTL_DEL) { 58 EV_SET(&kev[0], fd, EVFILT_READ, EV_DELETE, 0, 0, NULL); 59 EV_SET(&kev[1], fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); 60 EV_SET(&kev[2], fd, EVFILT_USER, EV_DELETE, 0, 0, NULL); 61 } else if (op == EPOLL_CTL_MOD) { 62 EV_SET(&kev[0], fd, EVFILT_READ, 63 event->events & EPOLLIN ? EV_ENABLE : EV_DISABLE, 0, 0, NULL); 64 EV_SET(&kev[1], fd, EVFILT_WRITE, 65 event->events & EPOLLOUT ? EV_ENABLE : EV_DISABLE, 0, 0, NULL); 66 EV_SET(&kev[2], fd, EVFILT_USER, 0, 67 NOTE_FFCOPY | (event->events & EPOLLRDHUP ? 1 : 0), 0, NULL); 68 } else { 69 ff_os_errno(ff_EINVAL); 70 return -1; 71 } 72 73 return ff_kevent(epfd, kev, 3, NULL, 0, NULL); 74 } 75 76 int 77 ff_epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout) 78 { 79 if (!events || maxevents < 1) { 80 ff_os_errno(ff_EINVAL); 81 return -1; 82 } 83 84 struct kevent *evlist = malloc(sizeof(struct kevent)*maxevents, M_DEVBUF, M_ZERO|M_NOWAIT); 85 if(NULL == evlist){ 86 ff_os_errno(ff_EINVAL); 87 return -1; 88 } 89 memset(evlist, 0, sizeof(struct kevent)*maxevents); 90 91 int ret = ff_kevent(epfd, NULL, 0, evlist, maxevents, NULL); 92 if (ret == -1) { 93 free(evlist, M_DEVBUF); 94 return ret; 95 } 96 97 unsigned int event_one = 0; 98 for (int i = 0; i < ret; ++i) { 99 event_one = 0; 100 if (evlist[i].filter & EVFILT_READ) { 101 event_one |= EPOLLIN; 102 } 103 if (evlist[i].filter & EVFILT_WRITE) { 104 event_one |= EPOLLOUT; 105 } 106 107 if (evlist[i].flags & EV_ERROR) { 108 event_one |= EPOLLERR; 109 } 110 111 if (evlist[i].flags & EV_EOF) { 112 event_one |= EPOLLIN; 113 } 114 events[i].events = event_one; 115 events[i].data.fd = evlist[i].ident; 116 } 117 118 free(evlist, M_DEVBUF); 119 return ret; 120 } 121 122 int 123 ff_epoll_close(int epfd) 124 { 125 return ff_close(epfd); 126 } 127 128