Annotation of embedaddon/lighttpd/src/fdevent_linux_sysepoll.c, revision 1.1.1.3
1.1.1.3 ! misho 1: #include "first.h"
! 2:
1.1 misho 3: #include "fdevent.h"
4: #include "buffer.h"
5: #include "log.h"
6:
7: #include <sys/types.h>
8:
9: #include <unistd.h>
10: #include <stdlib.h>
11: #include <stdio.h>
12: #include <string.h>
13: #include <errno.h>
14: #include <signal.h>
15: #include <fcntl.h>
16:
17: #ifdef USE_LINUX_EPOLL
18:
19: # include <sys/epoll.h>
20:
21: static void fdevent_linux_sysepoll_free(fdevents *ev) {
22: close(ev->epoll_fd);
23: free(ev->epoll_events);
24: }
25:
26: static int fdevent_linux_sysepoll_event_del(fdevents *ev, int fde_ndx, int fd) {
27: struct epoll_event ep;
28:
29: if (fde_ndx < 0) return -1;
30:
31: memset(&ep, 0, sizeof(ep));
32:
33: ep.data.fd = fd;
34: ep.data.ptr = NULL;
35:
36: if (0 != epoll_ctl(ev->epoll_fd, EPOLL_CTL_DEL, fd, &ep)) {
37: log_error_write(ev->srv, __FILE__, __LINE__, "SSS",
38: "epoll_ctl failed: ", strerror(errno), ", dying");
39:
40: SEGFAULT();
41:
42: return 0;
43: }
44:
45:
46: return -1;
47: }
48:
49: static int fdevent_linux_sysepoll_event_set(fdevents *ev, int fde_ndx, int fd, int events) {
50: struct epoll_event ep;
51: int add = 0;
52:
53: if (fde_ndx == -1) add = 1;
54:
55: memset(&ep, 0, sizeof(ep));
56:
57: ep.events = 0;
58:
59: if (events & FDEVENT_IN) ep.events |= EPOLLIN;
60: if (events & FDEVENT_OUT) ep.events |= EPOLLOUT;
61:
62: /**
63: *
64: * with EPOLLET we don't get a FDEVENT_HUP
65: * if the close is delay after everything has
66: * sent.
67: *
68: */
69:
70: ep.events |= EPOLLERR | EPOLLHUP /* | EPOLLET */;
71:
72: ep.data.ptr = NULL;
73: ep.data.fd = fd;
74:
75: if (0 != epoll_ctl(ev->epoll_fd, add ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, fd, &ep)) {
76: log_error_write(ev->srv, __FILE__, __LINE__, "SSS",
77: "epoll_ctl failed: ", strerror(errno), ", dying");
78:
79: SEGFAULT();
80:
81: return 0;
82: }
83:
84: return fd;
85: }
86:
87: static int fdevent_linux_sysepoll_poll(fdevents *ev, int timeout_ms) {
88: return epoll_wait(ev->epoll_fd, ev->epoll_events, ev->maxfds, timeout_ms);
89: }
90:
91: static int fdevent_linux_sysepoll_event_get_revent(fdevents *ev, size_t ndx) {
92: int events = 0, e;
93:
94: e = ev->epoll_events[ndx].events;
95: if (e & EPOLLIN) events |= FDEVENT_IN;
96: if (e & EPOLLOUT) events |= FDEVENT_OUT;
97: if (e & EPOLLERR) events |= FDEVENT_ERR;
98: if (e & EPOLLHUP) events |= FDEVENT_HUP;
99: if (e & EPOLLPRI) events |= FDEVENT_PRI;
100:
101: return events;
102: }
103:
104: static int fdevent_linux_sysepoll_event_get_fd(fdevents *ev, size_t ndx) {
105: # if 0
106: log_error_write(ev->srv, __FILE__, __LINE__, "SD, D",
107: "fdevent_linux_sysepoll_event_get_fd: ", (int) ndx, ev->epoll_events[ndx].data.fd);
108: # endif
109:
110: return ev->epoll_events[ndx].data.fd;
111: }
112:
113: static int fdevent_linux_sysepoll_event_next_fdndx(fdevents *ev, int ndx) {
114: size_t i;
115:
116: UNUSED(ev);
117:
118: i = (ndx < 0) ? 0 : ndx + 1;
119:
120: return i;
121: }
122:
123: int fdevent_linux_sysepoll_init(fdevents *ev) {
124: ev->type = FDEVENT_HANDLER_LINUX_SYSEPOLL;
125: #define SET(x) \
126: ev->x = fdevent_linux_sysepoll_##x;
127:
128: SET(free);
129: SET(poll);
130:
131: SET(event_del);
132: SET(event_set);
133:
134: SET(event_next_fdndx);
135: SET(event_get_fd);
136: SET(event_get_revent);
137:
138: if (-1 == (ev->epoll_fd = epoll_create(ev->maxfds))) {
139: log_error_write(ev->srv, __FILE__, __LINE__, "SSS",
140: "epoll_create failed (", strerror(errno), "), try to set server.event-handler = \"poll\" or \"select\"");
141:
142: return -1;
143: }
144:
1.1.1.2 misho 145: fd_close_on_exec(ev->epoll_fd);
1.1 misho 146:
147: ev->epoll_events = malloc(ev->maxfds * sizeof(*ev->epoll_events));
1.1.1.3 ! misho 148: force_assert(NULL != ev->epoll_events);
1.1 misho 149:
150: return 0;
151: }
152:
153: #else
154: int fdevent_linux_sysepoll_init(fdevents *ev) {
155: UNUSED(ev);
156:
157: log_error_write(ev->srv, __FILE__, __LINE__, "S",
158: "linux-sysepoll not supported, try to set server.event-handler = \"poll\" or \"select\"");
159:
160: return -1;
161: }
162: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>