5 #include "fdevent_impl.h"
10 #ifdef FDEVENT_USE_LIBEV
14 static void io_watcher_cb(struct ev_loop
*loop
, ev_io
*w
, int revents
) {
15 fdevents
*ev
= w
->data
;
16 fdevent_handler handler
= fdevent_get_handler(ev
, w
->fd
);
17 void *context
= fdevent_get_context(ev
, w
->fd
);
20 if (NULL
== handler
) return;
22 if (revents
& EV_READ
) r
|= FDEVENT_IN
;
23 if (revents
& EV_WRITE
) r
|= FDEVENT_OUT
;
24 if (revents
& EV_ERROR
) r
|= FDEVENT_ERR
;
26 switch (r
= (*handler
)(ev
->srv
, context
, r
)) {
27 case HANDLER_FINISHED
:
29 case HANDLER_WAIT_FOR_EVENT
:
30 case HANDLER_WAIT_FOR_FD
:
33 /* should never happen */
37 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "d", r
);
42 static void fdevent_libev_free(fdevents
*ev
) {
46 static int fdevent_libev_event_del(fdevents
*ev
, int fde_ndx
, int fd
) {
50 if (-1 == fde_ndx
) return -1;
52 fdn
= ev
->fdarray
[fd
];
53 watcher
= fdn
->handler_ctx
;
55 if (!watcher
) return -1;
57 ev_io_stop(ev
->libev_loop
, watcher
);
59 fdn
->handler_ctx
= NULL
;
64 static int fdevent_libev_event_set(fdevents
*ev
, int fde_ndx
, int fd
, int events
) {
65 fdnode
*fdn
= ev
->fdarray
[fd
];
66 ev_io
*watcher
= fdn
->handler_ctx
;
70 if (events
& FDEVENT_IN
) ev_events
|= EV_READ
;
71 if (events
& FDEVENT_OUT
) ev_events
|= EV_WRITE
;
74 fdn
->handler_ctx
= watcher
= calloc(1, sizeof(ev_io
));
75 force_assert(watcher
);
77 ev_io_init(watcher
, io_watcher_cb
, fd
, ev_events
);
79 ev_io_start(ev
->libev_loop
, watcher
);
81 if ((watcher
->events
& (EV_READ
| EV_WRITE
)) != ev_events
) {
82 ev_io_stop(ev
->libev_loop
, watcher
);
83 ev_io_set(watcher
, watcher
->fd
, ev_events
);
84 ev_io_start(ev
->libev_loop
, watcher
);
91 static void timeout_watcher_cb(struct ev_loop
*loop
, ev_timer
*w
, int revents
) {
97 static ev_timer timeout_watcher
;
99 static int fdevent_libev_poll(fdevents
*ev
, int timeout_ms
) {
100 timeout_watcher
.repeat
= (timeout_ms
> 0) ? timeout_ms
/1000.0 : 0.001;
102 ev_timer_again(ev
->libev_loop
, &timeout_watcher
);
103 ev_run(ev
->libev_loop
, EVRUN_ONCE
);
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
;
139 memset(timer
, 0, sizeof(*timer
));
141 ev
->type
= FDEVENT_HANDLER_LIBEV
;
143 ev->x = fdevent_libev_##x;
152 SET(event_next_fdndx
);
154 SET(event_get_revent
);
156 if (NULL
== (ev
->libev_loop
= ev_default_loop(0))) {
157 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "S",
158 "ev_default_loop failed , try to set server.event-handler = \"poll\" or \"select\"");
163 ev_timer_init(timer
, timeout_watcher_cb
, 0.0, 1.0);
169 int fdevent_libev_init(fdevents
*ev
) {
172 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "S",
173 "libev not supported, try to set server.event-handler = \"poll\" or \"select\"");