19 # include <sys/poll.h>
22 static void fdevent_poll_free(fdevents
*ev
) {
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
);
36 if (ev
->pollfds
[fde_ndx
].fd
== fd
) {
39 ev
->pollfds
[k
].fd
= -1;
40 /* ev->pollfds[k].events = 0; */
41 /* ev->pollfds[k].revents = 0; */
43 if (ev
->unused
.size
== 0) {
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
;
55 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "SdD",
56 "del! ", ev
->pollfds
[fde_ndx
].fd
, fd
);
65 static int fdevent_poll_event_compress(fdevents
*ev
) {
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
--;
77 static int fdevent_poll_event_set(fdevents
*ev
, int fde_ndx
, int fd
, int events
) {
79 if (events
& FDEVENT_IN
) pevents
|= POLLIN
;
80 if (events
& FDEVENT_OUT
) pevents
|= POLLOUT
;
85 if (ev
->pollfds
[fde_ndx
].fd
== fd
) {
86 ev
->pollfds
[fde_ndx
].events
= pevents
;
90 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "SdD",
91 "set: ", fde_ndx
, ev
->pollfds
[fde_ndx
].fd
);
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
;
105 ev
->pollfds
= malloc(sizeof(*ev
->pollfds
) * ev
->size
);
106 force_assert(NULL
!= ev
->pollfds
);
107 } else if (ev
->size
== ev
->used
) {
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
;
120 static int fdevent_poll_poll(fdevents
*ev
, int timeout_ms
) {
122 fdevent_poll_event_compress(ev
);
124 return poll(ev
->pollfds
, ev
->used
, timeout_ms
);
127 static int fdevent_poll_event_get_revent(fdevents
*ev
, size_t ndx
) {
130 if (ndx
>= ev
->used
) {
131 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "sii",
132 "dying because: event: ", (int) ndx
, (int) ev
->used
);
139 if (ev
->pollfds
[ndx
].revents
& POLLNVAL
) {
140 /* should never happen */
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
;
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
) {
166 i
= (ndx
< 0) ? 0 : ndx
+ 1;
167 for (; i
< ev
->used
; i
++) {
168 if (ev
->pollfds
[i
].revents
) return i
;
174 int fdevent_poll_init(fdevents
*ev
) {
175 ev
->type
= FDEVENT_HANDLER_POLL
;
177 ev->x = fdevent_poll_##x;
185 SET(event_next_fdndx
);
187 SET(event_get_revent
);
196 int fdevent_poll_init(fdevents
*ev
) {
199 log_error_write(ev
->srv
, __FILE__
, __LINE__
,
200 "s", "poll is not supported, try to set server.event-handler = \"select\"");