11 static void io_watcher_cb(struct ev_loop
*loop
, ev_io
*w
, int revents
) {
12 fdevents
*ev
= w
->data
;
13 fdevent_handler handler
= fdevent_get_handler(ev
, w
->fd
);
14 void *context
= fdevent_get_context(ev
, w
->fd
);
17 if (NULL
== handler
) return;
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
= (*handler
)(ev
->srv
, context
, 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
) {
94 static ev_timer timeout_watcher
;
96 static int fdevent_libev_poll(fdevents
*ev
, int timeout_ms
) {
97 timeout_watcher
.repeat
= (timeout_ms
> 0) ? timeout_ms
/1000.0 : 0.001;
99 ev_timer_again(ev
->libev_loop
, &timeout_watcher
);
100 ev_run(ev
->libev_loop
, EVRUN_ONCE
);
101 fdevent_sched_run(ev
->srv
, ev
);
106 static int fdevent_libev_event_get_revent(fdevents
*ev
, size_t ndx
) {
113 static int fdevent_libev_event_get_fd(fdevents
*ev
, size_t ndx
) {
120 static int fdevent_libev_event_next_fdndx(fdevents
*ev
, int ndx
) {
127 static int fdevent_libev_reset(fdevents
*ev
) {
135 int fdevent_libev_init(fdevents
*ev
) {
136 struct ev_timer
* const timer
= &timeout_watcher
;
137 memset(timer
, 0, sizeof(*timer
));
139 ev
->type
= FDEVENT_HANDLER_LIBEV
;
141 ev->x = fdevent_libev_##x;
150 SET(event_next_fdndx
);
152 SET(event_get_revent
);
154 if (NULL
== (ev
->libev_loop
= ev_default_loop(0))) {
155 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "S",
156 "ev_default_loop failed , try to set server.event-handler = \"poll\" or \"select\"");
161 ev_timer_init(timer
, timeout_watcher_cb
, 0.0, 1.0);
167 int fdevent_libev_init(fdevents
*ev
) {
170 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "S",
171 "libev not supported, try to set server.event-handler = \"poll\" or \"select\"");