22 # include <sys/poll.h>
25 static void fdevent_poll_free(fdevents
*ev
) {
27 if (ev
->unused
.ptr
) free(ev
->unused
.ptr
);
30 static int fdevent_poll_event_del(fdevents
*ev
, int fde_ndx
, int fd
) {
31 if (fde_ndx
< 0) return -1;
33 if ((size_t)fde_ndx
>= ev
->used
) {
34 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "SdD",
35 "del! out of range ", fde_ndx
, (int) ev
->used
);
39 if (ev
->pollfds
[fde_ndx
].fd
== fd
) {
42 ev
->pollfds
[k
].fd
= -1;
43 /* ev->pollfds[k].events = 0; */
44 /* ev->pollfds[k].revents = 0; */
46 if (ev
->unused
.size
== 0) {
48 ev
->unused
.ptr
= malloc(sizeof(*(ev
->unused
.ptr
)) * ev
->unused
.size
);
49 force_assert(NULL
!= ev
->unused
.ptr
);
50 } else if (ev
->unused
.size
== ev
->unused
.used
) {
51 ev
->unused
.size
+= 16;
52 ev
->unused
.ptr
= realloc(ev
->unused
.ptr
, sizeof(*(ev
->unused
.ptr
)) * ev
->unused
.size
);
53 force_assert(NULL
!= ev
->unused
.ptr
);
56 ev
->unused
.ptr
[ev
->unused
.used
++] = k
;
58 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "SdD",
59 "del! ", ev
->pollfds
[fde_ndx
].fd
, fd
);
68 static int fdevent_poll_event_compress(fdevents
*ev
) {
71 if (ev
->used
== 0) return 0;
72 if (ev
->unused
.used
!= 0) return 0;
74 for (j
= ev
->used
- 1; j
+ 1 > 0 && ev
->pollfds
[j
].fd
== -1; j
--) ev
->used
--;
80 static int fdevent_poll_event_set(fdevents
*ev
, int fde_ndx
, int fd
, int events
) {
82 if (events
& FDEVENT_IN
) pevents
|= POLLIN
;
83 if (events
& FDEVENT_OUT
) pevents
|= POLLOUT
;
88 if (ev
->pollfds
[fde_ndx
].fd
== fd
) {
89 ev
->pollfds
[fde_ndx
].events
= pevents
;
93 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "SdD",
94 "set: ", fde_ndx
, ev
->pollfds
[fde_ndx
].fd
);
98 if (ev
->unused
.used
> 0) {
99 int k
= ev
->unused
.ptr
[--ev
->unused
.used
];
101 ev
->pollfds
[k
].fd
= fd
;
102 ev
->pollfds
[k
].events
= pevents
;
108 ev
->pollfds
= malloc(sizeof(*ev
->pollfds
) * ev
->size
);
109 force_assert(NULL
!= ev
->pollfds
);
110 } else if (ev
->size
== ev
->used
) {
112 ev
->pollfds
= realloc(ev
->pollfds
, sizeof(*ev
->pollfds
) * ev
->size
);
113 force_assert(NULL
!= ev
->pollfds
);
116 ev
->pollfds
[ev
->used
].fd
= fd
;
117 ev
->pollfds
[ev
->used
].events
= pevents
;
123 static int fdevent_poll_poll(fdevents
*ev
, int timeout_ms
) {
125 fdevent_poll_event_compress(ev
);
127 return poll(ev
->pollfds
, ev
->used
, timeout_ms
);
130 static int fdevent_poll_event_get_revent(fdevents
*ev
, size_t ndx
) {
133 if (ndx
>= ev
->used
) {
134 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "sii",
135 "dying because: event: ", (int) ndx
, (int) ev
->used
);
142 if (ev
->pollfds
[ndx
].revents
& POLLNVAL
) {
143 /* should never happen */
148 poll_r
= ev
->pollfds
[ndx
].revents
;
150 /* map POLL* to FDEVEN_*; they are probably the same, but still. */
152 if (poll_r
& POLLIN
) r
|= FDEVENT_IN
;
153 if (poll_r
& POLLOUT
) r
|= FDEVENT_OUT
;
154 if (poll_r
& POLLERR
) r
|= FDEVENT_ERR
;
155 if (poll_r
& POLLHUP
) r
|= FDEVENT_HUP
;
156 if (poll_r
& POLLNVAL
) r
|= FDEVENT_NVAL
;
157 if (poll_r
& POLLPRI
) r
|= FDEVENT_PRI
;
162 static int fdevent_poll_event_get_fd(fdevents
*ev
, size_t ndx
) {
163 return ev
->pollfds
[ndx
].fd
;
166 static int fdevent_poll_event_next_fdndx(fdevents
*ev
, int ndx
) {
169 i
= (ndx
< 0) ? 0 : ndx
+ 1;
170 for (; i
< ev
->used
; i
++) {
171 if (ev
->pollfds
[i
].revents
) return i
;
177 int fdevent_poll_init(fdevents
*ev
) {
178 ev
->type
= FDEVENT_HANDLER_POLL
;
180 ev->x = fdevent_poll_##x;
188 SET(event_next_fdndx
);
190 SET(event_get_revent
);
199 int fdevent_poll_init(fdevents
*ev
) {
202 log_error_write(ev
->srv
, __FILE__
, __LINE__
,
203 "s", "poll is not supported, try to set server.event-handler = \"select\"");