13 static void io_watcher_cb(struct ev_loop
*loop
, ev_io
*w
, int revents
) {
14 fdevents
*ev
= w
->data
;
15 fdevent_handler handler
= fdevent_get_handler(ev
, w
->fd
);
16 void *context
= fdevent_get_context(ev
, w
->fd
);
19 if (NULL
== handler
) return;
21 if (revents
& EV_READ
) r
|= FDEVENT_IN
;
22 if (revents
& EV_WRITE
) r
|= FDEVENT_OUT
;
23 if (revents
& EV_ERROR
) r
|= FDEVENT_ERR
;
25 switch (r
= (*handler
)(ev
->srv
, context
, r
)) {
26 case HANDLER_FINISHED
:
28 case HANDLER_WAIT_FOR_EVENT
:
29 case HANDLER_WAIT_FOR_FD
:
32 /* should never happen */
36 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "d", r
);
41 static void fdevent_libev_free(fdevents
*ev
) {
45 static int fdevent_libev_event_del(fdevents
*ev
, int fde_ndx
, int fd
) {
49 if (-1 == fde_ndx
) return -1;
51 fdn
= ev
->fdarray
[fd
];
52 watcher
= fdn
->handler_ctx
;
54 if (!watcher
) return -1;
56 ev_io_stop(ev
->libev_loop
, watcher
);
58 fdn
->handler_ctx
= NULL
;
63 static int fdevent_libev_event_set(fdevents
*ev
, int fde_ndx
, int fd
, int events
) {
64 fdnode
*fdn
= ev
->fdarray
[fd
];
65 ev_io
*watcher
= fdn
->handler_ctx
;
69 if (events
& FDEVENT_IN
) ev_events
|= EV_READ
;
70 if (events
& FDEVENT_OUT
) ev_events
|= EV_WRITE
;
73 fdn
->handler_ctx
= watcher
= calloc(1, sizeof(ev_io
));
74 force_assert(watcher
);
76 ev_io_init(watcher
, io_watcher_cb
, fd
, ev_events
);
78 ev_io_start(ev
->libev_loop
, watcher
);
80 if ((watcher
->events
& (EV_READ
| EV_WRITE
)) != ev_events
) {
81 ev_io_stop(ev
->libev_loop
, watcher
);
82 ev_io_set(watcher
, watcher
->fd
, ev_events
);
83 ev_io_start(ev
->libev_loop
, watcher
);
90 static void timeout_watcher_cb(struct ev_loop
*loop
, ev_timer
*w
, int revents
) {
96 static ev_timer timeout_watcher
;
98 static int fdevent_libev_poll(fdevents
*ev
, int timeout_ms
) {
99 timeout_watcher
.repeat
= (timeout_ms
> 0) ? timeout_ms
/1000.0 : 0.001;
101 ev_timer_again(ev
->libev_loop
, &timeout_watcher
);
102 ev_run(ev
->libev_loop
, EVRUN_ONCE
);
103 fdevent_sched_run(ev
->srv
, ev
);
108 static int fdevent_libev_event_get_revent(fdevents
*ev
, size_t ndx
) {
115 static int fdevent_libev_event_get_fd(fdevents
*ev
, size_t ndx
) {
122 static int fdevent_libev_event_next_fdndx(fdevents
*ev
, int ndx
) {
129 static int fdevent_libev_reset(fdevents
*ev
) {
137 int fdevent_libev_init(fdevents
*ev
) {
138 struct ev_timer
* const timer
= &timeout_watcher
;
140 ev
->type
= FDEVENT_HANDLER_LIBEV
;
142 ev->x = fdevent_libev_##x;
151 SET(event_next_fdndx
);
153 SET(event_get_revent
);
155 if (NULL
== (ev
->libev_loop
= ev_default_loop(0))) {
156 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "S",
157 "ev_default_loop failed , try to set server.event-handler = \"poll\" or \"select\"");
162 ev_timer_init(timer
, timeout_watcher_cb
, 0.0, 1.0);
168 int fdevent_libev_init(fdevents
*ev
) {
171 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "S",
172 "libev not supported, try to set server.event-handler = \"poll\" or \"select\"");