[core] fdevent_cycle_logger()
[lighttpd.git] / src / fdevent_poll.c
blob3401b57d1a8f9e45f945f3a6f16f0e8797e38b5c
1 #include "first.h"
3 #include "fdevent.h"
4 #include "buffer.h"
5 #include "log.h"
7 #include <sys/types.h>
9 #include <unistd.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <errno.h>
14 #ifdef USE_POLL
16 # ifdef HAVE_POLL_H
17 # include <poll.h>
18 # else
19 # include <sys/poll.h>
20 # endif
22 static void fdevent_poll_free(fdevents *ev) {
23 free(ev->pollfds);
24 if (ev->unused.ptr) free(ev->unused.ptr);
27 static int fdevent_poll_event_del(fdevents *ev, int fde_ndx, int fd) {
28 if (fde_ndx < 0) return -1;
30 if ((size_t)fde_ndx >= ev->used) {
31 log_error_write(ev->srv, __FILE__, __LINE__, "SdD",
32 "del! out of range ", fde_ndx, (int) ev->used);
33 SEGFAULT();
36 if (ev->pollfds[fde_ndx].fd == fd) {
37 size_t k = fde_ndx;
39 ev->pollfds[k].fd = -1;
40 /* ev->pollfds[k].events = 0; */
41 /* ev->pollfds[k].revents = 0; */
43 if (ev->unused.size == 0) {
44 ev->unused.size = 16;
45 ev->unused.ptr = malloc(sizeof(*(ev->unused.ptr)) * ev->unused.size);
46 force_assert(NULL != ev->unused.ptr);
47 } else if (ev->unused.size == ev->unused.used) {
48 ev->unused.size += 16;
49 ev->unused.ptr = realloc(ev->unused.ptr, sizeof(*(ev->unused.ptr)) * ev->unused.size);
50 force_assert(NULL != ev->unused.ptr);
53 ev->unused.ptr[ev->unused.used++] = k;
54 } else {
55 log_error_write(ev->srv, __FILE__, __LINE__, "SdD",
56 "del! ", ev->pollfds[fde_ndx].fd, fd);
58 SEGFAULT();
61 return -1;
64 #if 0
65 static int fdevent_poll_event_compress(fdevents *ev) {
66 size_t j;
68 if (ev->used == 0) return 0;
69 if (ev->unused.used != 0) return 0;
71 for (j = ev->used - 1; j + 1 > 0 && ev->pollfds[j].fd == -1; j--) ev->used--;
73 return 0;
75 #endif
77 static int fdevent_poll_event_set(fdevents *ev, int fde_ndx, int fd, int events) {
78 int pevents = 0;
79 if (events & FDEVENT_IN) pevents |= POLLIN;
80 if (events & FDEVENT_OUT) pevents |= POLLOUT;
82 /* known index */
84 if (fde_ndx != -1) {
85 if (ev->pollfds[fde_ndx].fd == fd) {
86 ev->pollfds[fde_ndx].events = pevents;
88 return fde_ndx;
90 log_error_write(ev->srv, __FILE__, __LINE__, "SdD",
91 "set: ", fde_ndx, ev->pollfds[fde_ndx].fd);
92 SEGFAULT();
95 if (ev->unused.used > 0) {
96 int k = ev->unused.ptr[--ev->unused.used];
98 ev->pollfds[k].fd = fd;
99 ev->pollfds[k].events = pevents;
101 return k;
102 } else {
103 if (ev->size == 0) {
104 ev->size = 16;
105 ev->pollfds = malloc(sizeof(*ev->pollfds) * ev->size);
106 force_assert(NULL != ev->pollfds);
107 } else if (ev->size == ev->used) {
108 ev->size += 16;
109 ev->pollfds = realloc(ev->pollfds, sizeof(*ev->pollfds) * ev->size);
110 force_assert(NULL != ev->pollfds);
113 ev->pollfds[ev->used].fd = fd;
114 ev->pollfds[ev->used].events = pevents;
116 return ev->used++;
120 static int fdevent_poll_poll(fdevents *ev, int timeout_ms) {
121 #if 0
122 fdevent_poll_event_compress(ev);
123 #endif
124 return poll(ev->pollfds, ev->used, timeout_ms);
127 static int fdevent_poll_event_get_revent(fdevents *ev, size_t ndx) {
128 int r, poll_r;
130 if (ndx >= ev->used) {
131 log_error_write(ev->srv, __FILE__, __LINE__, "sii",
132 "dying because: event: ", (int) ndx, (int) ev->used);
134 SEGFAULT();
136 return 0;
139 if (ev->pollfds[ndx].revents & POLLNVAL) {
140 /* should never happen */
141 SEGFAULT();
144 r = 0;
145 poll_r = ev->pollfds[ndx].revents;
147 /* map POLL* to FDEVEN_*; they are probably the same, but still. */
149 if (poll_r & POLLIN) r |= FDEVENT_IN;
150 if (poll_r & POLLOUT) r |= FDEVENT_OUT;
151 if (poll_r & POLLERR) r |= FDEVENT_ERR;
152 if (poll_r & POLLHUP) r |= FDEVENT_HUP;
153 if (poll_r & POLLNVAL) r |= FDEVENT_NVAL;
154 if (poll_r & POLLPRI) r |= FDEVENT_PRI;
156 return r;
159 static int fdevent_poll_event_get_fd(fdevents *ev, size_t ndx) {
160 return ev->pollfds[ndx].fd;
163 static int fdevent_poll_event_next_fdndx(fdevents *ev, int ndx) {
164 size_t i;
166 i = (ndx < 0) ? 0 : ndx + 1;
167 for (; i < ev->used; i++) {
168 if (ev->pollfds[i].revents) return i;
171 return -1;
174 int fdevent_poll_init(fdevents *ev) {
175 ev->type = FDEVENT_HANDLER_POLL;
176 #define SET(x) \
177 ev->x = fdevent_poll_##x;
179 SET(free);
180 SET(poll);
182 SET(event_del);
183 SET(event_set);
185 SET(event_next_fdndx);
186 SET(event_get_fd);
187 SET(event_get_revent);
189 return 0;
195 #else
196 int fdevent_poll_init(fdevents *ev) {
197 UNUSED(ev);
199 log_error_write(ev->srv, __FILE__, __LINE__,
200 "s", "poll is not supported, try to set server.event-handler = \"select\"");
202 return -1;
204 #endif