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