1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker * libwebsockets - small server side websockets and web server implementation
3*1c60b9acSAndroid Build Coastguard Worker *
4*1c60b9acSAndroid Build Coastguard Worker * Copyright (C) 2010 - 2020 Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker *
6*1c60b9acSAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a copy
7*1c60b9acSAndroid Build Coastguard Worker * of this software and associated documentation files (the "Software"), to
8*1c60b9acSAndroid Build Coastguard Worker * deal in the Software without restriction, including without limitation the
9*1c60b9acSAndroid Build Coastguard Worker * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*1c60b9acSAndroid Build Coastguard Worker * sell copies of the Software, and to permit persons to whom the Software is
11*1c60b9acSAndroid Build Coastguard Worker * furnished to do so, subject to the following conditions:
12*1c60b9acSAndroid Build Coastguard Worker *
13*1c60b9acSAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included in
14*1c60b9acSAndroid Build Coastguard Worker * all copies or substantial portions of the Software.
15*1c60b9acSAndroid Build Coastguard Worker *
16*1c60b9acSAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*1c60b9acSAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*1c60b9acSAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*1c60b9acSAndroid Build Coastguard Worker * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*1c60b9acSAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*1c60b9acSAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22*1c60b9acSAndroid Build Coastguard Worker * IN THE SOFTWARE.
23*1c60b9acSAndroid Build Coastguard Worker */
24*1c60b9acSAndroid Build Coastguard Worker
25*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-core.h"
26*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-event-libs-libev.h"
27*1c60b9acSAndroid Build Coastguard Worker
28*1c60b9acSAndroid Build Coastguard Worker #define pt_to_priv_ev(_pt) ((struct lws_pt_eventlibs_libev *)(_pt)->evlib_pt)
29*1c60b9acSAndroid Build Coastguard Worker #define vh_to_priv_ev(_vh) ((struct lws_vh_eventlibs_libev *)(_vh)->evlib_vh)
30*1c60b9acSAndroid Build Coastguard Worker #define wsi_to_priv_ev(_w) ((struct lws_wsi_eventlibs_libev *)(_w)->evlib_wsi)
31*1c60b9acSAndroid Build Coastguard Worker
32*1c60b9acSAndroid Build Coastguard Worker static void
lws_ev_hrtimer_cb(struct ev_loop * loop,struct ev_timer * watcher,int revents)33*1c60b9acSAndroid Build Coastguard Worker lws_ev_hrtimer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents)
34*1c60b9acSAndroid Build Coastguard Worker {
35*1c60b9acSAndroid Build Coastguard Worker struct lws_pt_eventlibs_libev *ptpr = lws_container_of(watcher,
36*1c60b9acSAndroid Build Coastguard Worker struct lws_pt_eventlibs_libev, hrtimer);
37*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt = ptpr->pt;
38*1c60b9acSAndroid Build Coastguard Worker lws_usec_t us;
39*1c60b9acSAndroid Build Coastguard Worker
40*1c60b9acSAndroid Build Coastguard Worker lws_pt_lock(pt, __func__);
41*1c60b9acSAndroid Build Coastguard Worker us = __lws_sul_service_ripe(pt->pt_sul_owner, LWS_COUNT_PT_SUL_OWNERS,
42*1c60b9acSAndroid Build Coastguard Worker lws_now_usecs());
43*1c60b9acSAndroid Build Coastguard Worker if (us) {
44*1c60b9acSAndroid Build Coastguard Worker ev_timer_set(&ptpr->hrtimer, ((float)us) / 1000000.0, 0);
45*1c60b9acSAndroid Build Coastguard Worker ev_timer_start(ptpr->io_loop, &ptpr->hrtimer);
46*1c60b9acSAndroid Build Coastguard Worker }
47*1c60b9acSAndroid Build Coastguard Worker lws_pt_unlock(pt);
48*1c60b9acSAndroid Build Coastguard Worker }
49*1c60b9acSAndroid Build Coastguard Worker
50*1c60b9acSAndroid Build Coastguard Worker static void
lws_ev_idle_cb(struct ev_loop * loop,struct ev_idle * handle,int revents)51*1c60b9acSAndroid Build Coastguard Worker lws_ev_idle_cb(struct ev_loop *loop, struct ev_idle *handle, int revents)
52*1c60b9acSAndroid Build Coastguard Worker {
53*1c60b9acSAndroid Build Coastguard Worker struct lws_pt_eventlibs_libev *ptpr = lws_container_of(handle,
54*1c60b9acSAndroid Build Coastguard Worker struct lws_pt_eventlibs_libev, idle);
55*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt = ptpr->pt;
56*1c60b9acSAndroid Build Coastguard Worker int reschedule = 0;
57*1c60b9acSAndroid Build Coastguard Worker lws_usec_t us;
58*1c60b9acSAndroid Build Coastguard Worker
59*1c60b9acSAndroid Build Coastguard Worker lws_service_do_ripe_rxflow(pt);
60*1c60b9acSAndroid Build Coastguard Worker
61*1c60b9acSAndroid Build Coastguard Worker /*
62*1c60b9acSAndroid Build Coastguard Worker * is there anybody with pending stuff that needs service forcing?
63*1c60b9acSAndroid Build Coastguard Worker */
64*1c60b9acSAndroid Build Coastguard Worker if (!lws_service_adjust_timeout(pt->context, 1, pt->tid))
65*1c60b9acSAndroid Build Coastguard Worker /* -1 timeout means just do forced service */
66*1c60b9acSAndroid Build Coastguard Worker reschedule = _lws_plat_service_forced_tsi(pt->context, pt->tid);
67*1c60b9acSAndroid Build Coastguard Worker
68*1c60b9acSAndroid Build Coastguard Worker /* account for hrtimer */
69*1c60b9acSAndroid Build Coastguard Worker
70*1c60b9acSAndroid Build Coastguard Worker lws_pt_lock(pt, __func__);
71*1c60b9acSAndroid Build Coastguard Worker us = __lws_sul_service_ripe(pt->pt_sul_owner, LWS_COUNT_PT_SUL_OWNERS,
72*1c60b9acSAndroid Build Coastguard Worker lws_now_usecs());
73*1c60b9acSAndroid Build Coastguard Worker if (us) {
74*1c60b9acSAndroid Build Coastguard Worker ev_timer_set(&ptpr->hrtimer, ((float)us) / 1000000.0, 0);
75*1c60b9acSAndroid Build Coastguard Worker ev_timer_start(ptpr->io_loop, &ptpr->hrtimer);
76*1c60b9acSAndroid Build Coastguard Worker }
77*1c60b9acSAndroid Build Coastguard Worker lws_pt_unlock(pt);
78*1c60b9acSAndroid Build Coastguard Worker
79*1c60b9acSAndroid Build Coastguard Worker /* there is nobody who needs service forcing, shut down idle */
80*1c60b9acSAndroid Build Coastguard Worker if (!reschedule)
81*1c60b9acSAndroid Build Coastguard Worker ev_idle_stop(loop, handle);
82*1c60b9acSAndroid Build Coastguard Worker
83*1c60b9acSAndroid Build Coastguard Worker if (pt->destroy_self)
84*1c60b9acSAndroid Build Coastguard Worker lws_context_destroy(pt->context);
85*1c60b9acSAndroid Build Coastguard Worker }
86*1c60b9acSAndroid Build Coastguard Worker
87*1c60b9acSAndroid Build Coastguard Worker static void
lws_accept_cb(struct ev_loop * loop,struct ev_io * watcher,int revents)88*1c60b9acSAndroid Build Coastguard Worker lws_accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
89*1c60b9acSAndroid Build Coastguard Worker {
90*1c60b9acSAndroid Build Coastguard Worker struct lws_io_watcher_libev *lws_io = lws_container_of(watcher,
91*1c60b9acSAndroid Build Coastguard Worker struct lws_io_watcher_libev, watcher);
92*1c60b9acSAndroid Build Coastguard Worker struct lws_context *context = lws_io->context;
93*1c60b9acSAndroid Build Coastguard Worker struct lws_pt_eventlibs_libev *ptpr;
94*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt;
95*1c60b9acSAndroid Build Coastguard Worker struct lws_pollfd eventfd;
96*1c60b9acSAndroid Build Coastguard Worker struct lws *wsi;
97*1c60b9acSAndroid Build Coastguard Worker
98*1c60b9acSAndroid Build Coastguard Worker if (revents & EV_ERROR)
99*1c60b9acSAndroid Build Coastguard Worker return;
100*1c60b9acSAndroid Build Coastguard Worker
101*1c60b9acSAndroid Build Coastguard Worker eventfd.fd = watcher->fd;
102*1c60b9acSAndroid Build Coastguard Worker eventfd.events = 0;
103*1c60b9acSAndroid Build Coastguard Worker eventfd.revents = EV_NONE;
104*1c60b9acSAndroid Build Coastguard Worker
105*1c60b9acSAndroid Build Coastguard Worker if (revents & EV_READ) {
106*1c60b9acSAndroid Build Coastguard Worker eventfd.events |= LWS_POLLIN;
107*1c60b9acSAndroid Build Coastguard Worker eventfd.revents |= LWS_POLLIN;
108*1c60b9acSAndroid Build Coastguard Worker }
109*1c60b9acSAndroid Build Coastguard Worker if (revents & EV_WRITE) {
110*1c60b9acSAndroid Build Coastguard Worker eventfd.events |= LWS_POLLOUT;
111*1c60b9acSAndroid Build Coastguard Worker eventfd.revents |= LWS_POLLOUT;
112*1c60b9acSAndroid Build Coastguard Worker }
113*1c60b9acSAndroid Build Coastguard Worker
114*1c60b9acSAndroid Build Coastguard Worker wsi = wsi_from_fd(context, watcher->fd);
115*1c60b9acSAndroid Build Coastguard Worker pt = &context->pt[(int)wsi->tsi];
116*1c60b9acSAndroid Build Coastguard Worker ptpr = pt_to_priv_ev(pt);
117*1c60b9acSAndroid Build Coastguard Worker
118*1c60b9acSAndroid Build Coastguard Worker lws_service_fd_tsi(context, &eventfd, (int)wsi->tsi);
119*1c60b9acSAndroid Build Coastguard Worker
120*1c60b9acSAndroid Build Coastguard Worker ev_idle_start(ptpr->io_loop, &ptpr->idle);
121*1c60b9acSAndroid Build Coastguard Worker }
122*1c60b9acSAndroid Build Coastguard Worker
123*1c60b9acSAndroid Build Coastguard Worker void
lws_ev_sigint_cb(struct ev_loop * loop,struct ev_signal * watcher,int revents)124*1c60b9acSAndroid Build Coastguard Worker lws_ev_sigint_cb(struct ev_loop *loop, struct ev_signal *watcher, int revents)
125*1c60b9acSAndroid Build Coastguard Worker {
126*1c60b9acSAndroid Build Coastguard Worker struct lws_context *context = watcher->data;
127*1c60b9acSAndroid Build Coastguard Worker
128*1c60b9acSAndroid Build Coastguard Worker if (context->eventlib_signal_cb) {
129*1c60b9acSAndroid Build Coastguard Worker context->eventlib_signal_cb((void *)watcher, watcher->signum);
130*1c60b9acSAndroid Build Coastguard Worker
131*1c60b9acSAndroid Build Coastguard Worker return;
132*1c60b9acSAndroid Build Coastguard Worker }
133*1c60b9acSAndroid Build Coastguard Worker ev_break(loop, EVBREAK_ALL);
134*1c60b9acSAndroid Build Coastguard Worker }
135*1c60b9acSAndroid Build Coastguard Worker
136*1c60b9acSAndroid Build Coastguard Worker static int
elops_listen_init_ev(struct lws_dll2 * d,void * user)137*1c60b9acSAndroid Build Coastguard Worker elops_listen_init_ev(struct lws_dll2 *d, void *user)
138*1c60b9acSAndroid Build Coastguard Worker {
139*1c60b9acSAndroid Build Coastguard Worker struct lws *wsi = lws_container_of(d, struct lws, listen_list);
140*1c60b9acSAndroid Build Coastguard Worker struct lws_context *context = (struct lws_context *)user;
141*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
142*1c60b9acSAndroid Build Coastguard Worker struct lws_pt_eventlibs_libev *ptpr = pt_to_priv_ev(pt);
143*1c60b9acSAndroid Build Coastguard Worker struct lws_wsi_eventlibs_libev *w = wsi_to_priv_ev(wsi);
144*1c60b9acSAndroid Build Coastguard Worker struct lws_vhost *vh = wsi->a.vhost;
145*1c60b9acSAndroid Build Coastguard Worker
146*1c60b9acSAndroid Build Coastguard Worker w->w_read.context = context;
147*1c60b9acSAndroid Build Coastguard Worker w->w_write.context = context;
148*1c60b9acSAndroid Build Coastguard Worker vh_to_priv_ev(vh)->w_accept.context = context;
149*1c60b9acSAndroid Build Coastguard Worker
150*1c60b9acSAndroid Build Coastguard Worker ev_io_init(&vh_to_priv_ev(vh)->w_accept.watcher,
151*1c60b9acSAndroid Build Coastguard Worker lws_accept_cb, wsi->desc.sockfd, EV_READ);
152*1c60b9acSAndroid Build Coastguard Worker ev_io_start(ptpr->io_loop, &vh_to_priv_ev(vh)->w_accept.watcher);
153*1c60b9acSAndroid Build Coastguard Worker
154*1c60b9acSAndroid Build Coastguard Worker return 0;
155*1c60b9acSAndroid Build Coastguard Worker }
156*1c60b9acSAndroid Build Coastguard Worker
157*1c60b9acSAndroid Build Coastguard Worker static int
elops_init_pt_ev(struct lws_context * context,void * _loop,int tsi)158*1c60b9acSAndroid Build Coastguard Worker elops_init_pt_ev(struct lws_context *context, void *_loop, int tsi)
159*1c60b9acSAndroid Build Coastguard Worker {
160*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt = &context->pt[tsi];
161*1c60b9acSAndroid Build Coastguard Worker struct lws_pt_eventlibs_libev *ptpr = pt_to_priv_ev(pt);
162*1c60b9acSAndroid Build Coastguard Worker struct ev_signal *w_sigint = &ptpr->w_sigint.watcher;
163*1c60b9acSAndroid Build Coastguard Worker struct ev_loop *loop = (struct ev_loop *)_loop;
164*1c60b9acSAndroid Build Coastguard Worker const char *backend_name;
165*1c60b9acSAndroid Build Coastguard Worker unsigned int backend;
166*1c60b9acSAndroid Build Coastguard Worker int status = 0;
167*1c60b9acSAndroid Build Coastguard Worker
168*1c60b9acSAndroid Build Coastguard Worker lwsl_cx_info(context, "loop %p", _loop);
169*1c60b9acSAndroid Build Coastguard Worker
170*1c60b9acSAndroid Build Coastguard Worker ptpr->pt = pt;
171*1c60b9acSAndroid Build Coastguard Worker
172*1c60b9acSAndroid Build Coastguard Worker if (!loop)
173*1c60b9acSAndroid Build Coastguard Worker loop = ev_loop_new(0);
174*1c60b9acSAndroid Build Coastguard Worker else
175*1c60b9acSAndroid Build Coastguard Worker context->pt[tsi].event_loop_foreign = 1;
176*1c60b9acSAndroid Build Coastguard Worker
177*1c60b9acSAndroid Build Coastguard Worker if (!loop) {
178*1c60b9acSAndroid Build Coastguard Worker lwsl_cx_err(context, "creating event base failed");
179*1c60b9acSAndroid Build Coastguard Worker
180*1c60b9acSAndroid Build Coastguard Worker return -1;
181*1c60b9acSAndroid Build Coastguard Worker }
182*1c60b9acSAndroid Build Coastguard Worker
183*1c60b9acSAndroid Build Coastguard Worker ptpr->io_loop = loop;
184*1c60b9acSAndroid Build Coastguard Worker
185*1c60b9acSAndroid Build Coastguard Worker lws_vhost_foreach_listen_wsi(context, context, elops_listen_init_ev);
186*1c60b9acSAndroid Build Coastguard Worker
187*1c60b9acSAndroid Build Coastguard Worker /* Register the signal watcher unless it's a foreign loop */
188*1c60b9acSAndroid Build Coastguard Worker if (!context->pt[tsi].event_loop_foreign) {
189*1c60b9acSAndroid Build Coastguard Worker ev_signal_init(w_sigint, lws_ev_sigint_cb, SIGINT);
190*1c60b9acSAndroid Build Coastguard Worker w_sigint->data = context;
191*1c60b9acSAndroid Build Coastguard Worker ev_signal_start(loop, w_sigint);
192*1c60b9acSAndroid Build Coastguard Worker }
193*1c60b9acSAndroid Build Coastguard Worker
194*1c60b9acSAndroid Build Coastguard Worker backend = ev_backend(loop);
195*1c60b9acSAndroid Build Coastguard Worker switch (backend) {
196*1c60b9acSAndroid Build Coastguard Worker case EVBACKEND_SELECT:
197*1c60b9acSAndroid Build Coastguard Worker backend_name = "select";
198*1c60b9acSAndroid Build Coastguard Worker break;
199*1c60b9acSAndroid Build Coastguard Worker case EVBACKEND_POLL:
200*1c60b9acSAndroid Build Coastguard Worker backend_name = "poll";
201*1c60b9acSAndroid Build Coastguard Worker break;
202*1c60b9acSAndroid Build Coastguard Worker case EVBACKEND_EPOLL:
203*1c60b9acSAndroid Build Coastguard Worker backend_name = "epoll";
204*1c60b9acSAndroid Build Coastguard Worker break;
205*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVBACKEND_LINUXAIO)
206*1c60b9acSAndroid Build Coastguard Worker case EVBACKEND_LINUXAIO:
207*1c60b9acSAndroid Build Coastguard Worker backend_name = "Linux AIO";
208*1c60b9acSAndroid Build Coastguard Worker break;
209*1c60b9acSAndroid Build Coastguard Worker #endif
210*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_HAVE_EVBACKEND_IOURING)
211*1c60b9acSAndroid Build Coastguard Worker case EVBACKEND_IOURING:
212*1c60b9acSAndroid Build Coastguard Worker backend_name = "Linux io_uring";
213*1c60b9acSAndroid Build Coastguard Worker break;
214*1c60b9acSAndroid Build Coastguard Worker #endif
215*1c60b9acSAndroid Build Coastguard Worker case EVBACKEND_KQUEUE:
216*1c60b9acSAndroid Build Coastguard Worker backend_name = "kqueue";
217*1c60b9acSAndroid Build Coastguard Worker break;
218*1c60b9acSAndroid Build Coastguard Worker case EVBACKEND_DEVPOLL:
219*1c60b9acSAndroid Build Coastguard Worker backend_name = "/dev/poll";
220*1c60b9acSAndroid Build Coastguard Worker break;
221*1c60b9acSAndroid Build Coastguard Worker case EVBACKEND_PORT:
222*1c60b9acSAndroid Build Coastguard Worker backend_name = "Solaris 10 \"port\"";
223*1c60b9acSAndroid Build Coastguard Worker break;
224*1c60b9acSAndroid Build Coastguard Worker default:
225*1c60b9acSAndroid Build Coastguard Worker backend_name = "Unknown libev backend";
226*1c60b9acSAndroid Build Coastguard Worker break;
227*1c60b9acSAndroid Build Coastguard Worker }
228*1c60b9acSAndroid Build Coastguard Worker
229*1c60b9acSAndroid Build Coastguard Worker lwsl_cx_info(context, " libev backend: %s", backend_name);
230*1c60b9acSAndroid Build Coastguard Worker (void)backend_name;
231*1c60b9acSAndroid Build Coastguard Worker
232*1c60b9acSAndroid Build Coastguard Worker ev_timer_init(&ptpr->hrtimer, lws_ev_hrtimer_cb, 0, 0);
233*1c60b9acSAndroid Build Coastguard Worker ptpr->hrtimer.data = pt;
234*1c60b9acSAndroid Build Coastguard Worker
235*1c60b9acSAndroid Build Coastguard Worker ev_idle_init(&ptpr->idle, lws_ev_idle_cb);
236*1c60b9acSAndroid Build Coastguard Worker
237*1c60b9acSAndroid Build Coastguard Worker return status;
238*1c60b9acSAndroid Build Coastguard Worker }
239*1c60b9acSAndroid Build Coastguard Worker
240*1c60b9acSAndroid Build Coastguard Worker static int
elops_listen_destroy_ev(struct lws_dll2 * d,void * user)241*1c60b9acSAndroid Build Coastguard Worker elops_listen_destroy_ev(struct lws_dll2 *d, void *user)
242*1c60b9acSAndroid Build Coastguard Worker {
243*1c60b9acSAndroid Build Coastguard Worker struct lws *wsi = lws_container_of(d, struct lws, listen_list);
244*1c60b9acSAndroid Build Coastguard Worker struct lws_context *context = (struct lws_context *)user;
245*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
246*1c60b9acSAndroid Build Coastguard Worker struct lws_pt_eventlibs_libev *ptpr = pt_to_priv_ev(pt);
247*1c60b9acSAndroid Build Coastguard Worker struct lws_vhost *vh = wsi->a.vhost;
248*1c60b9acSAndroid Build Coastguard Worker
249*1c60b9acSAndroid Build Coastguard Worker ev_io_stop(ptpr->io_loop, &vh_to_priv_ev(vh)->w_accept.watcher);
250*1c60b9acSAndroid Build Coastguard Worker
251*1c60b9acSAndroid Build Coastguard Worker return 0;
252*1c60b9acSAndroid Build Coastguard Worker }
253*1c60b9acSAndroid Build Coastguard Worker
254*1c60b9acSAndroid Build Coastguard Worker static void
elops_destroy_pt_ev(struct lws_context * context,int tsi)255*1c60b9acSAndroid Build Coastguard Worker elops_destroy_pt_ev(struct lws_context *context, int tsi)
256*1c60b9acSAndroid Build Coastguard Worker {
257*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt = &context->pt[tsi];
258*1c60b9acSAndroid Build Coastguard Worker struct lws_pt_eventlibs_libev *ptpr = pt_to_priv_ev(pt);
259*1c60b9acSAndroid Build Coastguard Worker
260*1c60b9acSAndroid Build Coastguard Worker lws_vhost_foreach_listen_wsi(context, context, elops_listen_destroy_ev);
261*1c60b9acSAndroid Build Coastguard Worker
262*1c60b9acSAndroid Build Coastguard Worker /* static assets */
263*1c60b9acSAndroid Build Coastguard Worker
264*1c60b9acSAndroid Build Coastguard Worker ev_timer_stop(ptpr->io_loop, &ptpr->hrtimer);
265*1c60b9acSAndroid Build Coastguard Worker ev_idle_stop(ptpr->io_loop, &ptpr->idle);
266*1c60b9acSAndroid Build Coastguard Worker
267*1c60b9acSAndroid Build Coastguard Worker if (!pt->event_loop_foreign)
268*1c60b9acSAndroid Build Coastguard Worker ev_signal_stop(ptpr->io_loop, &ptpr->w_sigint.watcher);
269*1c60b9acSAndroid Build Coastguard Worker }
270*1c60b9acSAndroid Build Coastguard Worker
271*1c60b9acSAndroid Build Coastguard Worker static int
elops_init_context_ev(struct lws_context * context,const struct lws_context_creation_info * info)272*1c60b9acSAndroid Build Coastguard Worker elops_init_context_ev(struct lws_context *context,
273*1c60b9acSAndroid Build Coastguard Worker const struct lws_context_creation_info *info)
274*1c60b9acSAndroid Build Coastguard Worker {
275*1c60b9acSAndroid Build Coastguard Worker int n;
276*1c60b9acSAndroid Build Coastguard Worker
277*1c60b9acSAndroid Build Coastguard Worker context->eventlib_signal_cb = info->signal_cb;
278*1c60b9acSAndroid Build Coastguard Worker
279*1c60b9acSAndroid Build Coastguard Worker for (n = 0; n < context->count_threads; n++)
280*1c60b9acSAndroid Build Coastguard Worker pt_to_priv_ev(&context->pt[n])->w_sigint.context = context;
281*1c60b9acSAndroid Build Coastguard Worker
282*1c60b9acSAndroid Build Coastguard Worker return 0;
283*1c60b9acSAndroid Build Coastguard Worker }
284*1c60b9acSAndroid Build Coastguard Worker
285*1c60b9acSAndroid Build Coastguard Worker static int
elops_accept_ev(struct lws * wsi)286*1c60b9acSAndroid Build Coastguard Worker elops_accept_ev(struct lws *wsi)
287*1c60b9acSAndroid Build Coastguard Worker {
288*1c60b9acSAndroid Build Coastguard Worker struct lws_wsi_eventlibs_libev *w = wsi_to_priv_ev(wsi);
289*1c60b9acSAndroid Build Coastguard Worker int fd;
290*1c60b9acSAndroid Build Coastguard Worker
291*1c60b9acSAndroid Build Coastguard Worker if (wsi->role_ops->file_handle)
292*1c60b9acSAndroid Build Coastguard Worker fd = wsi->desc.filefd;
293*1c60b9acSAndroid Build Coastguard Worker else
294*1c60b9acSAndroid Build Coastguard Worker fd = wsi->desc.sockfd;
295*1c60b9acSAndroid Build Coastguard Worker
296*1c60b9acSAndroid Build Coastguard Worker w->w_read.context = wsi->a.context;
297*1c60b9acSAndroid Build Coastguard Worker w->w_write.context = wsi->a.context;
298*1c60b9acSAndroid Build Coastguard Worker
299*1c60b9acSAndroid Build Coastguard Worker ev_io_init(&w->w_read.watcher, lws_accept_cb, fd, EV_READ);
300*1c60b9acSAndroid Build Coastguard Worker ev_io_init(&w->w_write.watcher, lws_accept_cb, fd, EV_WRITE);
301*1c60b9acSAndroid Build Coastguard Worker
302*1c60b9acSAndroid Build Coastguard Worker return 0;
303*1c60b9acSAndroid Build Coastguard Worker }
304*1c60b9acSAndroid Build Coastguard Worker
305*1c60b9acSAndroid Build Coastguard Worker static void
elops_io_ev(struct lws * wsi,unsigned int flags)306*1c60b9acSAndroid Build Coastguard Worker elops_io_ev(struct lws *wsi, unsigned int flags)
307*1c60b9acSAndroid Build Coastguard Worker {
308*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
309*1c60b9acSAndroid Build Coastguard Worker struct lws_pt_eventlibs_libev *ptpr = pt_to_priv_ev(pt);
310*1c60b9acSAndroid Build Coastguard Worker struct lws_wsi_eventlibs_libev *w = wsi_to_priv_ev(wsi);
311*1c60b9acSAndroid Build Coastguard Worker
312*1c60b9acSAndroid Build Coastguard Worker lwsl_wsi_debug(wsi, "%s flags 0x%x %p %d", wsi->role_ops->name, flags,
313*1c60b9acSAndroid Build Coastguard Worker ptpr->io_loop,
314*1c60b9acSAndroid Build Coastguard Worker pt->is_destroyed);
315*1c60b9acSAndroid Build Coastguard Worker
316*1c60b9acSAndroid Build Coastguard Worker if (!ptpr->io_loop || pt->is_destroyed)
317*1c60b9acSAndroid Build Coastguard Worker return;
318*1c60b9acSAndroid Build Coastguard Worker
319*1c60b9acSAndroid Build Coastguard Worker assert((flags & (LWS_EV_START | LWS_EV_STOP)) &&
320*1c60b9acSAndroid Build Coastguard Worker (flags & (LWS_EV_READ | LWS_EV_WRITE)));
321*1c60b9acSAndroid Build Coastguard Worker
322*1c60b9acSAndroid Build Coastguard Worker if (flags & LWS_EV_START) {
323*1c60b9acSAndroid Build Coastguard Worker if (flags & LWS_EV_WRITE)
324*1c60b9acSAndroid Build Coastguard Worker ev_io_start(ptpr->io_loop, &w->w_write.watcher);
325*1c60b9acSAndroid Build Coastguard Worker if (flags & LWS_EV_READ)
326*1c60b9acSAndroid Build Coastguard Worker ev_io_start(ptpr->io_loop, &w->w_read.watcher);
327*1c60b9acSAndroid Build Coastguard Worker } else {
328*1c60b9acSAndroid Build Coastguard Worker if (flags & LWS_EV_WRITE)
329*1c60b9acSAndroid Build Coastguard Worker ev_io_stop(ptpr->io_loop, &w->w_write.watcher);
330*1c60b9acSAndroid Build Coastguard Worker if (flags & LWS_EV_READ)
331*1c60b9acSAndroid Build Coastguard Worker ev_io_stop(ptpr->io_loop, &w->w_read.watcher);
332*1c60b9acSAndroid Build Coastguard Worker }
333*1c60b9acSAndroid Build Coastguard Worker
334*1c60b9acSAndroid Build Coastguard Worker if (pt->destroy_self)
335*1c60b9acSAndroid Build Coastguard Worker lws_context_destroy(pt->context);
336*1c60b9acSAndroid Build Coastguard Worker }
337*1c60b9acSAndroid Build Coastguard Worker
338*1c60b9acSAndroid Build Coastguard Worker static void
elops_run_pt_ev(struct lws_context * context,int tsi)339*1c60b9acSAndroid Build Coastguard Worker elops_run_pt_ev(struct lws_context *context, int tsi)
340*1c60b9acSAndroid Build Coastguard Worker {
341*1c60b9acSAndroid Build Coastguard Worker if (pt_to_priv_ev(&context->pt[tsi])->io_loop)
342*1c60b9acSAndroid Build Coastguard Worker ev_run(pt_to_priv_ev(&context->pt[tsi])->io_loop, 0);
343*1c60b9acSAndroid Build Coastguard Worker }
344*1c60b9acSAndroid Build Coastguard Worker
345*1c60b9acSAndroid Build Coastguard Worker static int
elops_destroy_context2_ev(struct lws_context * context)346*1c60b9acSAndroid Build Coastguard Worker elops_destroy_context2_ev(struct lws_context *context)
347*1c60b9acSAndroid Build Coastguard Worker {
348*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt;
349*1c60b9acSAndroid Build Coastguard Worker struct lws_pt_eventlibs_libev *ptpr;
350*1c60b9acSAndroid Build Coastguard Worker int n, m;
351*1c60b9acSAndroid Build Coastguard Worker
352*1c60b9acSAndroid Build Coastguard Worker for (n = 0; n < context->count_threads; n++) {
353*1c60b9acSAndroid Build Coastguard Worker int budget = 1000;
354*1c60b9acSAndroid Build Coastguard Worker
355*1c60b9acSAndroid Build Coastguard Worker pt = &context->pt[n];
356*1c60b9acSAndroid Build Coastguard Worker ptpr = pt_to_priv_ev(pt);
357*1c60b9acSAndroid Build Coastguard Worker
358*1c60b9acSAndroid Build Coastguard Worker /* only for internal loops... */
359*1c60b9acSAndroid Build Coastguard Worker
360*1c60b9acSAndroid Build Coastguard Worker if (pt->event_loop_foreign || !ptpr->io_loop)
361*1c60b9acSAndroid Build Coastguard Worker continue;
362*1c60b9acSAndroid Build Coastguard Worker
363*1c60b9acSAndroid Build Coastguard Worker if (!context->evlib_finalize_destroy_after_int_loops_stop) {
364*1c60b9acSAndroid Build Coastguard Worker ev_break(ptpr->io_loop, EVBREAK_ONE);
365*1c60b9acSAndroid Build Coastguard Worker continue;
366*1c60b9acSAndroid Build Coastguard Worker }
367*1c60b9acSAndroid Build Coastguard Worker while (budget-- &&
368*1c60b9acSAndroid Build Coastguard Worker (m = ev_run(ptpr->io_loop, 0)))
369*1c60b9acSAndroid Build Coastguard Worker ;
370*1c60b9acSAndroid Build Coastguard Worker
371*1c60b9acSAndroid Build Coastguard Worker ev_loop_destroy(ptpr->io_loop);
372*1c60b9acSAndroid Build Coastguard Worker }
373*1c60b9acSAndroid Build Coastguard Worker
374*1c60b9acSAndroid Build Coastguard Worker return 0;
375*1c60b9acSAndroid Build Coastguard Worker }
376*1c60b9acSAndroid Build Coastguard Worker
377*1c60b9acSAndroid Build Coastguard Worker static int
elops_init_vhost_listen_wsi_ev(struct lws * wsi)378*1c60b9acSAndroid Build Coastguard Worker elops_init_vhost_listen_wsi_ev(struct lws *wsi)
379*1c60b9acSAndroid Build Coastguard Worker {
380*1c60b9acSAndroid Build Coastguard Worker struct lws_wsi_eventlibs_libev *w;
381*1c60b9acSAndroid Build Coastguard Worker int fd;
382*1c60b9acSAndroid Build Coastguard Worker
383*1c60b9acSAndroid Build Coastguard Worker if (!wsi) {
384*1c60b9acSAndroid Build Coastguard Worker assert(0);
385*1c60b9acSAndroid Build Coastguard Worker return 0;
386*1c60b9acSAndroid Build Coastguard Worker }
387*1c60b9acSAndroid Build Coastguard Worker
388*1c60b9acSAndroid Build Coastguard Worker w = wsi_to_priv_ev(wsi);
389*1c60b9acSAndroid Build Coastguard Worker w->w_read.context = wsi->a.context;
390*1c60b9acSAndroid Build Coastguard Worker w->w_write.context = wsi->a.context;
391*1c60b9acSAndroid Build Coastguard Worker
392*1c60b9acSAndroid Build Coastguard Worker if (wsi->role_ops->file_handle)
393*1c60b9acSAndroid Build Coastguard Worker fd = wsi->desc.filefd;
394*1c60b9acSAndroid Build Coastguard Worker else
395*1c60b9acSAndroid Build Coastguard Worker fd = wsi->desc.sockfd;
396*1c60b9acSAndroid Build Coastguard Worker
397*1c60b9acSAndroid Build Coastguard Worker ev_io_init(&w->w_read.watcher, lws_accept_cb, fd, EV_READ);
398*1c60b9acSAndroid Build Coastguard Worker //ev_io_init(&w->w_write.watcher, lws_accept_cb, fd, EV_WRITE);
399*1c60b9acSAndroid Build Coastguard Worker
400*1c60b9acSAndroid Build Coastguard Worker elops_io_ev(wsi, LWS_EV_START | LWS_EV_READ);
401*1c60b9acSAndroid Build Coastguard Worker
402*1c60b9acSAndroid Build Coastguard Worker return 0;
403*1c60b9acSAndroid Build Coastguard Worker }
404*1c60b9acSAndroid Build Coastguard Worker
405*1c60b9acSAndroid Build Coastguard Worker static void
elops_destroy_wsi_ev(struct lws * wsi)406*1c60b9acSAndroid Build Coastguard Worker elops_destroy_wsi_ev(struct lws *wsi)
407*1c60b9acSAndroid Build Coastguard Worker {
408*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
409*1c60b9acSAndroid Build Coastguard Worker struct lws_pt_eventlibs_libev *ptpr = pt_to_priv_ev(pt);
410*1c60b9acSAndroid Build Coastguard Worker struct lws_wsi_eventlibs_libev *w = wsi_to_priv_ev(wsi);
411*1c60b9acSAndroid Build Coastguard Worker
412*1c60b9acSAndroid Build Coastguard Worker ev_io_stop(ptpr->io_loop, &w->w_read.watcher);
413*1c60b9acSAndroid Build Coastguard Worker ev_io_stop(ptpr->io_loop, &w->w_write.watcher);
414*1c60b9acSAndroid Build Coastguard Worker }
415*1c60b9acSAndroid Build Coastguard Worker
416*1c60b9acSAndroid Build Coastguard Worker static const struct lws_event_loop_ops event_loop_ops_ev = {
417*1c60b9acSAndroid Build Coastguard Worker /* name */ "libev",
418*1c60b9acSAndroid Build Coastguard Worker /* init_context */ elops_init_context_ev,
419*1c60b9acSAndroid Build Coastguard Worker /* destroy_context1 */ NULL,
420*1c60b9acSAndroid Build Coastguard Worker /* destroy_context2 */ elops_destroy_context2_ev,
421*1c60b9acSAndroid Build Coastguard Worker /* init_vhost_listen_wsi */ elops_init_vhost_listen_wsi_ev,
422*1c60b9acSAndroid Build Coastguard Worker /* init_pt */ elops_init_pt_ev,
423*1c60b9acSAndroid Build Coastguard Worker /* wsi_logical_close */ NULL,
424*1c60b9acSAndroid Build Coastguard Worker /* check_client_connect_ok */ NULL,
425*1c60b9acSAndroid Build Coastguard Worker /* close_handle_manually */ NULL,
426*1c60b9acSAndroid Build Coastguard Worker /* accept */ elops_accept_ev,
427*1c60b9acSAndroid Build Coastguard Worker /* io */ elops_io_ev,
428*1c60b9acSAndroid Build Coastguard Worker /* run_pt */ elops_run_pt_ev,
429*1c60b9acSAndroid Build Coastguard Worker /* destroy_pt */ elops_destroy_pt_ev,
430*1c60b9acSAndroid Build Coastguard Worker /* destroy wsi */ elops_destroy_wsi_ev,
431*1c60b9acSAndroid Build Coastguard Worker /* foreign_thread */ NULL,
432*1c60b9acSAndroid Build Coastguard Worker
433*1c60b9acSAndroid Build Coastguard Worker /* flags */ 0,
434*1c60b9acSAndroid Build Coastguard Worker
435*1c60b9acSAndroid Build Coastguard Worker /* evlib_size_ctx */ 0,
436*1c60b9acSAndroid Build Coastguard Worker /* evlib_size_pt */ sizeof(struct lws_pt_eventlibs_libev),
437*1c60b9acSAndroid Build Coastguard Worker /* evlib_size_vh */ sizeof(struct lws_vh_eventlibs_libev),
438*1c60b9acSAndroid Build Coastguard Worker /* evlib_size_wsi */ sizeof(struct lws_wsi_eventlibs_libev),
439*1c60b9acSAndroid Build Coastguard Worker };
440*1c60b9acSAndroid Build Coastguard Worker
441*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_EVLIB_PLUGINS)
442*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE
443*1c60b9acSAndroid Build Coastguard Worker #endif
444*1c60b9acSAndroid Build Coastguard Worker const lws_plugin_evlib_t evlib_ev = {
445*1c60b9acSAndroid Build Coastguard Worker .hdr = {
446*1c60b9acSAndroid Build Coastguard Worker "libev event loop",
447*1c60b9acSAndroid Build Coastguard Worker "lws_evlib_plugin",
448*1c60b9acSAndroid Build Coastguard Worker LWS_BUILD_HASH,
449*1c60b9acSAndroid Build Coastguard Worker LWS_PLUGIN_API_MAGIC
450*1c60b9acSAndroid Build Coastguard Worker },
451*1c60b9acSAndroid Build Coastguard Worker
452*1c60b9acSAndroid Build Coastguard Worker .ops = &event_loop_ops_ev
453*1c60b9acSAndroid Build Coastguard Worker };
454