xref: /f-stack/lib/ff_epoll.c (revision a9643ea8)
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