13 static void io_watcher_cb(struct ev_loop
*loop
, ev_io
*w
, int revents
) {
14 fdevents
*ev
= w
->data
;
15 fdnode
*fdn
= ev
->fdarray
[w
->fd
];
19 if (revents
& EV_READ
) r
|= FDEVENT_IN
;
20 if (revents
& EV_WRITE
) r
|= FDEVENT_OUT
;
21 if (revents
& EV_ERROR
) r
|= FDEVENT_ERR
;
23 switch (r
= (*fdn
->handler
)(ev
->srv
, fdn
->ctx
, r
)) {
24 case HANDLER_FINISHED
:
26 case HANDLER_WAIT_FOR_EVENT
:
27 case HANDLER_WAIT_FOR_FD
:
30 /* should never happen */
34 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "d", r
);
39 static void fdevent_libev_free(fdevents
*ev
) {
43 static int fdevent_libev_event_del(fdevents
*ev
, int fde_ndx
, int fd
) {
47 if (-1 == fde_ndx
) return -1;
49 fdn
= ev
->fdarray
[fd
];
50 watcher
= fdn
->handler_ctx
;
52 if (!watcher
) return -1;
54 ev_io_stop(ev
->libev_loop
, watcher
);
56 fdn
->handler_ctx
= NULL
;
61 static int fdevent_libev_event_set(fdevents
*ev
, int fde_ndx
, int fd
, int events
) {
62 fdnode
*fdn
= ev
->fdarray
[fd
];
63 ev_io
*watcher
= fdn
->handler_ctx
;
67 if (events
& FDEVENT_IN
) ev_events
|= EV_READ
;
68 if (events
& FDEVENT_OUT
) ev_events
|= EV_WRITE
;
71 fdn
->handler_ctx
= watcher
= calloc(1, sizeof(ev_io
));
72 force_assert(watcher
);
74 ev_io_init(watcher
, io_watcher_cb
, fd
, ev_events
);
76 ev_io_start(ev
->libev_loop
, watcher
);
78 if ((watcher
->events
& (EV_READ
| EV_WRITE
)) != ev_events
) {
79 ev_io_stop(ev
->libev_loop
, watcher
);
80 ev_io_set(watcher
, watcher
->fd
, ev_events
);
81 ev_io_start(ev
->libev_loop
, watcher
);
88 static void timeout_watcher_cb(struct ev_loop
*loop
, ev_timer
*w
, int revents
) {
93 ev_timer_stop(loop
, w
);
97 static int fdevent_libev_poll(fdevents
*ev
, int timeout_ms
) {
100 struct ev_timer timer
;
103 if (!timeout_ms
) timeout_ms
= 1;
105 ev_init(&timeout_watcher
.w
, NULL
);
106 ev_set_cb(&timeout_watcher
.timer
, timeout_watcher_cb
);
107 timeout_watcher
.timer
.repeat
= ((ev_tstamp
) timeout_ms
)/1000.0;
108 force_assert(timeout_watcher
.timer
.repeat
);
109 ev_timer_again(ev
->libev_loop
, &timeout_watcher
.timer
);
111 ev_loop(ev
->libev_loop
, EVLOOP_ONESHOT
);
113 ev_timer_stop(ev
->libev_loop
, &timeout_watcher
.timer
);
118 static int fdevent_libev_event_get_revent(fdevents
*ev
, size_t ndx
) {
125 static int fdevent_libev_event_get_fd(fdevents
*ev
, size_t ndx
) {
132 static int fdevent_libev_event_next_fdndx(fdevents
*ev
, int ndx
) {
139 static int fdevent_libev_reset(fdevents
*ev
) {
147 int fdevent_libev_init(fdevents
*ev
) {
148 ev
->type
= FDEVENT_HANDLER_LIBEV
;
150 ev->x = fdevent_libev_##x;
159 SET(event_next_fdndx
);
161 SET(event_get_revent
);
163 if (NULL
== (ev
->libev_loop
= ev_default_loop(0))) {
164 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "S",
165 "ev_default_loop failed , try to set server.event-handler = \"poll\" or \"select\"");
174 int fdevent_libev_init(fdevents
*ev
) {
177 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "S",
178 "libev not supported, try to set server.event-handler = \"poll\" or \"select\"");