1 #include <stdio.h> 2 #include <stdint.h> 3 #include <string.h> 4 #include <stdlib.h> 5 #include <stdarg.h> 6 #include <sched.h> 7 #include <fcntl.h> 8 #include <errno.h> 9 #include <assert.h> 10 #include <unistd.h> 11 #include <netinet/in.h> 12 #include <sys/types.h> 13 #include <sys/socket.h> 14 #include <sys/time.h> 15 #include <sys/select.h> 16 #include <sys/syscall.h> 17 #include <arpa/inet.h> 18 #include <sys/epoll.h> 19 20 #include "ff_api.h" 21 #include "ff_errno.h" 22 23 24 int 25 ff_epoll_create(int size __attribute__((__unused__))) 26 { 27 return ff_kqueue(); 28 } 29 30 int 31 ff_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) 32 { 33 struct kevent kev[3]; 34 35 if (!event && op != EPOLL_CTL_DEL) { 36 errno = EINVAL; 37 return -1; 38 } 39 40 if (op == EPOLL_CTL_ADD){ 41 EV_SET(&kev[0], fd, EVFILT_READ, 42 EV_ADD | (event->events & EPOLLIN ? 0 : EV_DISABLE), 0, 0, NULL); 43 EV_SET(&kev[1], fd, EVFILT_WRITE, 44 EV_ADD | (event->events & EPOLLOUT ? 0 : EV_DISABLE), 0, 0, NULL); 45 EV_SET(&kev[2], fd, EVFILT_USER, EV_ADD, 46 event->events & EPOLLRDHUP ? 1 : 0, 0, NULL); 47 } else if (op == EPOLL_CTL_DEL) { 48 EV_SET(&kev[0], fd, EVFILT_READ, EV_DELETE, 0, 0, NULL); 49 EV_SET(&kev[1], fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); 50 EV_SET(&kev[2], fd, EVFILT_USER, EV_DELETE, 0, 0, NULL); 51 } else if (op == EPOLL_CTL_MOD) { 52 EV_SET(&kev[0], fd, EVFILT_READ, 53 event->events & EPOLLIN ? EV_ENABLE : EV_DISABLE, 0, 0, NULL); 54 EV_SET(&kev[1], fd, EVFILT_WRITE, 55 event->events & EPOLLOUT ? EV_ENABLE : EV_DISABLE, 0, 0, NULL); 56 EV_SET(&kev[2], fd, EVFILT_USER, 0, 57 NOTE_FFCOPY | (event->events & EPOLLRDHUP ? 1 : 0), 0, NULL); 58 } else { 59 errno = EINVAL; 60 return -1; 61 } 62 63 return ff_kevent(epfd, kev, 3, NULL, 0, NULL); 64 } 65 66 static void 67 ff_event_to_epoll(void **ev, struct kevent *kev) 68 { 69 unsigned int event_one = 0; 70 struct epoll_event **ppev = (struct epoll_event **)ev; 71 72 if (kev->filter == EVFILT_READ) { 73 if (kev->data || !(kev->flags & EV_EOF)) { 74 event_one |= EPOLLIN; 75 } 76 } else if (kev->filter == EVFILT_WRITE) { 77 event_one |= EPOLLOUT; 78 } 79 80 if (kev->flags & EV_ERROR) { 81 event_one |= EPOLLERR; 82 } 83 84 if (kev->flags & EV_EOF) { 85 event_one |= EPOLLHUP; 86 87 if (kev->fflags) { 88 event_one |= EPOLLERR; 89 } 90 91 if (kev->filter == EVFILT_READ) { 92 event_one |= EPOLLIN; 93 } else if (kev->filter == EVFILT_WRITE) { 94 event_one |= EPOLLERR; 95 } 96 } 97 98 (*ppev)->events = event_one; 99 (*ppev)->data.fd = kev->ident; 100 (*ppev)++; 101 } 102 103 int 104 ff_epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout) 105 { 106 int i, ret; 107 if (!events || maxevents < 1) { 108 errno = EINVAL; 109 return -1; 110 } 111 112 return ff_kevent_do_each(epfd, NULL, 0, events, maxevents, NULL, ff_event_to_epoll); 113 } 114 115