1*1c60b9acSAndroid Build Coastguard Worker #include <systemd/sd-event.h>
2*1c60b9acSAndroid Build Coastguard Worker
3*1c60b9acSAndroid Build Coastguard Worker #include <private-lib-core.h>
4*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-event-libs-sdevent.h"
5*1c60b9acSAndroid Build Coastguard Worker
6*1c60b9acSAndroid Build Coastguard Worker #define pt_to_priv_sd(_pt) ((struct lws_pt_eventlibs_sdevent *)(_pt)->evlib_pt)
7*1c60b9acSAndroid Build Coastguard Worker #define wsi_to_priv_sd(_w) ((struct lws_wsi_watcher_sdevent *)(_w)->evlib_wsi)
8*1c60b9acSAndroid Build Coastguard Worker
9*1c60b9acSAndroid Build Coastguard Worker struct lws_pt_eventlibs_sdevent {
10*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt;
11*1c60b9acSAndroid Build Coastguard Worker struct sd_event *io_loop;
12*1c60b9acSAndroid Build Coastguard Worker struct sd_event_source *sultimer;
13*1c60b9acSAndroid Build Coastguard Worker struct sd_event_source *idletimer;
14*1c60b9acSAndroid Build Coastguard Worker };
15*1c60b9acSAndroid Build Coastguard Worker
16*1c60b9acSAndroid Build Coastguard Worker struct lws_wsi_watcher_sdevent {
17*1c60b9acSAndroid Build Coastguard Worker struct sd_event_source *source;
18*1c60b9acSAndroid Build Coastguard Worker uint32_t events;
19*1c60b9acSAndroid Build Coastguard Worker };
20*1c60b9acSAndroid Build Coastguard Worker
21*1c60b9acSAndroid Build Coastguard Worker static int
sultimer_handler(sd_event_source * s,uint64_t usec,void * userdata)22*1c60b9acSAndroid Build Coastguard Worker sultimer_handler(sd_event_source *s, uint64_t usec, void *userdata)
23*1c60b9acSAndroid Build Coastguard Worker {
24*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt = (struct lws_context_per_thread *)userdata;
25*1c60b9acSAndroid Build Coastguard Worker
26*1c60b9acSAndroid Build Coastguard Worker lws_usec_t us;
27*1c60b9acSAndroid Build Coastguard Worker
28*1c60b9acSAndroid Build Coastguard Worker lws_context_lock(pt->context, __func__);
29*1c60b9acSAndroid Build Coastguard Worker lws_pt_lock(pt, __func__);
30*1c60b9acSAndroid Build Coastguard Worker
31*1c60b9acSAndroid Build Coastguard Worker us = __lws_sul_service_ripe(pt->pt_sul_owner, LWS_COUNT_PT_SUL_OWNERS,
32*1c60b9acSAndroid Build Coastguard Worker lws_now_usecs());
33*1c60b9acSAndroid Build Coastguard Worker if (us) {
34*1c60b9acSAndroid Build Coastguard Worker uint64_t at;
35*1c60b9acSAndroid Build Coastguard Worker
36*1c60b9acSAndroid Build Coastguard Worker sd_event_now(sd_event_source_get_event(s), CLOCK_MONOTONIC, &at);
37*1c60b9acSAndroid Build Coastguard Worker at += (uint64_t)us;
38*1c60b9acSAndroid Build Coastguard Worker sd_event_source_set_time(pt_to_priv_sd(pt)->sultimer, at);
39*1c60b9acSAndroid Build Coastguard Worker sd_event_source_set_enabled(pt_to_priv_sd(pt)->sultimer,
40*1c60b9acSAndroid Build Coastguard Worker SD_EVENT_ONESHOT);
41*1c60b9acSAndroid Build Coastguard Worker }
42*1c60b9acSAndroid Build Coastguard Worker
43*1c60b9acSAndroid Build Coastguard Worker lws_pt_unlock(pt);
44*1c60b9acSAndroid Build Coastguard Worker lws_context_unlock(pt->context);
45*1c60b9acSAndroid Build Coastguard Worker
46*1c60b9acSAndroid Build Coastguard Worker return 0;
47*1c60b9acSAndroid Build Coastguard Worker }
48*1c60b9acSAndroid Build Coastguard Worker
49*1c60b9acSAndroid Build Coastguard Worker static int
idle_handler(sd_event_source * s,uint64_t usec,void * userdata)50*1c60b9acSAndroid Build Coastguard Worker idle_handler(sd_event_source *s, uint64_t usec, void *userdata)
51*1c60b9acSAndroid Build Coastguard Worker {
52*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt = (struct lws_context_per_thread *)userdata;
53*1c60b9acSAndroid Build Coastguard Worker
54*1c60b9acSAndroid Build Coastguard Worker lws_usec_t us;
55*1c60b9acSAndroid Build Coastguard Worker
56*1c60b9acSAndroid Build Coastguard Worker lws_service_do_ripe_rxflow(pt);
57*1c60b9acSAndroid Build Coastguard Worker
58*1c60b9acSAndroid Build Coastguard Worker lws_context_lock(pt->context, __func__);
59*1c60b9acSAndroid Build Coastguard Worker lws_pt_lock(pt, __func__);
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 _lws_plat_service_forced_tsi(pt->context, pt->tid);
67*1c60b9acSAndroid Build Coastguard Worker
68*1c60b9acSAndroid Build Coastguard Worker /* account for sultimer */
69*1c60b9acSAndroid Build Coastguard Worker
70*1c60b9acSAndroid Build Coastguard Worker us = __lws_sul_service_ripe(pt->pt_sul_owner, LWS_COUNT_PT_SUL_OWNERS,
71*1c60b9acSAndroid Build Coastguard Worker lws_now_usecs());
72*1c60b9acSAndroid Build Coastguard Worker
73*1c60b9acSAndroid Build Coastguard Worker if (us) {
74*1c60b9acSAndroid Build Coastguard Worker uint64_t at;
75*1c60b9acSAndroid Build Coastguard Worker
76*1c60b9acSAndroid Build Coastguard Worker sd_event_now(sd_event_source_get_event(s), CLOCK_MONOTONIC, &at);
77*1c60b9acSAndroid Build Coastguard Worker at += (uint64_t)us;
78*1c60b9acSAndroid Build Coastguard Worker sd_event_source_set_time(pt_to_priv_sd(pt)->sultimer, at);
79*1c60b9acSAndroid Build Coastguard Worker sd_event_source_set_enabled(pt_to_priv_sd(pt)->sultimer,
80*1c60b9acSAndroid Build Coastguard Worker SD_EVENT_ONESHOT);
81*1c60b9acSAndroid Build Coastguard Worker }
82*1c60b9acSAndroid Build Coastguard Worker
83*1c60b9acSAndroid Build Coastguard Worker sd_event_source_set_enabled(pt_to_priv_sd(pt)->idletimer, SD_EVENT_OFF);
84*1c60b9acSAndroid Build Coastguard Worker
85*1c60b9acSAndroid Build Coastguard Worker lws_pt_unlock(pt);
86*1c60b9acSAndroid Build Coastguard Worker lws_context_unlock(pt->context);
87*1c60b9acSAndroid Build Coastguard Worker
88*1c60b9acSAndroid Build Coastguard Worker return 0;
89*1c60b9acSAndroid Build Coastguard Worker }
90*1c60b9acSAndroid Build Coastguard Worker
91*1c60b9acSAndroid Build Coastguard Worker static int
sock_accept_handler(sd_event_source * s,int fd,uint32_t revents,void * userdata)92*1c60b9acSAndroid Build Coastguard Worker sock_accept_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata)
93*1c60b9acSAndroid Build Coastguard Worker {
94*1c60b9acSAndroid Build Coastguard Worker struct lws *wsi = (struct lws *)userdata;
95*1c60b9acSAndroid Build Coastguard Worker struct lws_context *context = wsi->a.context;
96*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
97*1c60b9acSAndroid Build Coastguard Worker struct sd_event_source *idletimer, *watcher;
98*1c60b9acSAndroid Build Coastguard Worker struct lws_pollfd eventfd;
99*1c60b9acSAndroid Build Coastguard Worker
100*1c60b9acSAndroid Build Coastguard Worker lws_context_lock(pt->context, __func__);
101*1c60b9acSAndroid Build Coastguard Worker lws_pt_lock(pt, __func__);
102*1c60b9acSAndroid Build Coastguard Worker
103*1c60b9acSAndroid Build Coastguard Worker if (pt->is_destroyed)
104*1c60b9acSAndroid Build Coastguard Worker goto bail;
105*1c60b9acSAndroid Build Coastguard Worker
106*1c60b9acSAndroid Build Coastguard Worker eventfd.fd = fd;
107*1c60b9acSAndroid Build Coastguard Worker eventfd.events = 0;
108*1c60b9acSAndroid Build Coastguard Worker eventfd.revents = 0;
109*1c60b9acSAndroid Build Coastguard Worker
110*1c60b9acSAndroid Build Coastguard Worker if (revents & EPOLLIN) {
111*1c60b9acSAndroid Build Coastguard Worker eventfd.events |= LWS_POLLIN;
112*1c60b9acSAndroid Build Coastguard Worker eventfd.revents |= LWS_POLLIN;
113*1c60b9acSAndroid Build Coastguard Worker }
114*1c60b9acSAndroid Build Coastguard Worker
115*1c60b9acSAndroid Build Coastguard Worker if (revents & EPOLLOUT) {
116*1c60b9acSAndroid Build Coastguard Worker eventfd.events |= LWS_POLLOUT;
117*1c60b9acSAndroid Build Coastguard Worker eventfd.revents |= LWS_POLLOUT;
118*1c60b9acSAndroid Build Coastguard Worker }
119*1c60b9acSAndroid Build Coastguard Worker
120*1c60b9acSAndroid Build Coastguard Worker lws_pt_unlock(pt);
121*1c60b9acSAndroid Build Coastguard Worker lws_context_unlock(pt->context);
122*1c60b9acSAndroid Build Coastguard Worker
123*1c60b9acSAndroid Build Coastguard Worker lws_service_fd_tsi(context, &eventfd, wsi->tsi);
124*1c60b9acSAndroid Build Coastguard Worker
125*1c60b9acSAndroid Build Coastguard Worker if (pt->destroy_self) {
126*1c60b9acSAndroid Build Coastguard Worker lws_context_destroy(pt->context);
127*1c60b9acSAndroid Build Coastguard Worker return -1;
128*1c60b9acSAndroid Build Coastguard Worker }
129*1c60b9acSAndroid Build Coastguard Worker
130*1c60b9acSAndroid Build Coastguard Worker /* fire idle handler */
131*1c60b9acSAndroid Build Coastguard Worker idletimer = pt_to_priv_sd(pt)->idletimer;
132*1c60b9acSAndroid Build Coastguard Worker if (idletimer) {
133*1c60b9acSAndroid Build Coastguard Worker sd_event_source_set_time(idletimer, (uint64_t) 0);
134*1c60b9acSAndroid Build Coastguard Worker sd_event_source_set_enabled(idletimer, SD_EVENT_ON);
135*1c60b9acSAndroid Build Coastguard Worker }
136*1c60b9acSAndroid Build Coastguard Worker
137*1c60b9acSAndroid Build Coastguard Worker /*
138*1c60b9acSAndroid Build Coastguard Worker * allow further events
139*1c60b9acSAndroid Build Coastguard Worker *
140*1c60b9acSAndroid Build Coastguard Worker * Note:
141*1c60b9acSAndroid Build Coastguard Worker * do not move the assignment up, lws_service_fd_tsi may invalidate it!
142*1c60b9acSAndroid Build Coastguard Worker */
143*1c60b9acSAndroid Build Coastguard Worker watcher = wsi_to_priv_sd(wsi)->source;
144*1c60b9acSAndroid Build Coastguard Worker if (watcher)
145*1c60b9acSAndroid Build Coastguard Worker sd_event_source_set_enabled(watcher, SD_EVENT_ONESHOT);
146*1c60b9acSAndroid Build Coastguard Worker
147*1c60b9acSAndroid Build Coastguard Worker return 0;
148*1c60b9acSAndroid Build Coastguard Worker
149*1c60b9acSAndroid Build Coastguard Worker bail:
150*1c60b9acSAndroid Build Coastguard Worker lws_pt_unlock(pt);
151*1c60b9acSAndroid Build Coastguard Worker lws_context_unlock(pt->context);
152*1c60b9acSAndroid Build Coastguard Worker
153*1c60b9acSAndroid Build Coastguard Worker return -1;
154*1c60b9acSAndroid Build Coastguard Worker }
155*1c60b9acSAndroid Build Coastguard Worker
156*1c60b9acSAndroid Build Coastguard Worker static void
io_sd(struct lws * wsi,unsigned int flags)157*1c60b9acSAndroid Build Coastguard Worker io_sd(struct lws *wsi, unsigned int flags)
158*1c60b9acSAndroid Build Coastguard Worker {
159*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
160*1c60b9acSAndroid Build Coastguard Worker
161*1c60b9acSAndroid Build Coastguard Worker /*
162*1c60b9acSAndroid Build Coastguard Worker * Only manipulate if there is an event source, and if
163*1c60b9acSAndroid Build Coastguard Worker * the pt is still alive
164*1c60b9acSAndroid Build Coastguard Worker */
165*1c60b9acSAndroid Build Coastguard Worker if (!pt_to_priv_sd(pt)->io_loop ||
166*1c60b9acSAndroid Build Coastguard Worker !wsi_to_priv_sd(wsi)->source ||
167*1c60b9acSAndroid Build Coastguard Worker pt->is_destroyed)
168*1c60b9acSAndroid Build Coastguard Worker return;
169*1c60b9acSAndroid Build Coastguard Worker
170*1c60b9acSAndroid Build Coastguard Worker // assert that the requested flags do not contain anything unexpected
171*1c60b9acSAndroid Build Coastguard Worker if (!((flags & (LWS_EV_START | LWS_EV_STOP)) &&
172*1c60b9acSAndroid Build Coastguard Worker (flags & (LWS_EV_READ | LWS_EV_WRITE)))) {
173*1c60b9acSAndroid Build Coastguard Worker lwsl_wsi_err(wsi, "assert: flags %d", flags);
174*1c60b9acSAndroid Build Coastguard Worker assert(0);
175*1c60b9acSAndroid Build Coastguard Worker }
176*1c60b9acSAndroid Build Coastguard Worker
177*1c60b9acSAndroid Build Coastguard Worker // we are overdoing a bit here, so it resembles the structure in libuv.c
178*1c60b9acSAndroid Build Coastguard Worker if (flags & LWS_EV_START) {
179*1c60b9acSAndroid Build Coastguard Worker if (flags & LWS_EV_WRITE)
180*1c60b9acSAndroid Build Coastguard Worker wsi_to_priv_sd(wsi)->events |= EPOLLOUT;
181*1c60b9acSAndroid Build Coastguard Worker
182*1c60b9acSAndroid Build Coastguard Worker if (flags & LWS_EV_READ)
183*1c60b9acSAndroid Build Coastguard Worker wsi_to_priv_sd(wsi)->events |= EPOLLIN;
184*1c60b9acSAndroid Build Coastguard Worker
185*1c60b9acSAndroid Build Coastguard Worker sd_event_source_set_io_events(wsi_to_priv_sd(wsi)->source,
186*1c60b9acSAndroid Build Coastguard Worker wsi_to_priv_sd(wsi)->events);
187*1c60b9acSAndroid Build Coastguard Worker sd_event_source_set_enabled(wsi_to_priv_sd(wsi)->source,
188*1c60b9acSAndroid Build Coastguard Worker SD_EVENT_ONESHOT);
189*1c60b9acSAndroid Build Coastguard Worker } else {
190*1c60b9acSAndroid Build Coastguard Worker if (flags & LWS_EV_WRITE)
191*1c60b9acSAndroid Build Coastguard Worker wsi_to_priv_sd(wsi)->events =
192*1c60b9acSAndroid Build Coastguard Worker wsi_to_priv_sd(wsi)->events &
193*1c60b9acSAndroid Build Coastguard Worker (uint32_t)(~EPOLLOUT);
194*1c60b9acSAndroid Build Coastguard Worker
195*1c60b9acSAndroid Build Coastguard Worker if (flags & LWS_EV_READ)
196*1c60b9acSAndroid Build Coastguard Worker wsi_to_priv_sd(wsi)->events =
197*1c60b9acSAndroid Build Coastguard Worker wsi_to_priv_sd(wsi)->events &
198*1c60b9acSAndroid Build Coastguard Worker (uint32_t)(~EPOLLIN);
199*1c60b9acSAndroid Build Coastguard Worker
200*1c60b9acSAndroid Build Coastguard Worker sd_event_source_set_io_events(wsi_to_priv_sd(wsi)->source,
201*1c60b9acSAndroid Build Coastguard Worker wsi_to_priv_sd(wsi)->events);
202*1c60b9acSAndroid Build Coastguard Worker
203*1c60b9acSAndroid Build Coastguard Worker if (!(wsi_to_priv_sd(wsi)->events & (EPOLLIN | EPOLLOUT)))
204*1c60b9acSAndroid Build Coastguard Worker sd_event_source_set_enabled(wsi_to_priv_sd(wsi)->source,
205*1c60b9acSAndroid Build Coastguard Worker SD_EVENT_ONESHOT);
206*1c60b9acSAndroid Build Coastguard Worker else
207*1c60b9acSAndroid Build Coastguard Worker sd_event_source_set_enabled(wsi_to_priv_sd(wsi)->source,
208*1c60b9acSAndroid Build Coastguard Worker SD_EVENT_OFF);
209*1c60b9acSAndroid Build Coastguard Worker }
210*1c60b9acSAndroid Build Coastguard Worker }
211*1c60b9acSAndroid Build Coastguard Worker
212*1c60b9acSAndroid Build Coastguard Worker static int
init_vhost_listen_wsi_sd(struct lws * wsi)213*1c60b9acSAndroid Build Coastguard Worker init_vhost_listen_wsi_sd(struct lws *wsi)
214*1c60b9acSAndroid Build Coastguard Worker {
215*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt;
216*1c60b9acSAndroid Build Coastguard Worker
217*1c60b9acSAndroid Build Coastguard Worker if (!wsi)
218*1c60b9acSAndroid Build Coastguard Worker return 0;
219*1c60b9acSAndroid Build Coastguard Worker
220*1c60b9acSAndroid Build Coastguard Worker pt = &wsi->a.context->pt[(int)wsi->tsi];
221*1c60b9acSAndroid Build Coastguard Worker
222*1c60b9acSAndroid Build Coastguard Worker sd_event_add_io(pt_to_priv_sd(pt)->io_loop,
223*1c60b9acSAndroid Build Coastguard Worker &wsi_to_priv_sd(wsi)->source,
224*1c60b9acSAndroid Build Coastguard Worker wsi->desc.sockfd,
225*1c60b9acSAndroid Build Coastguard Worker wsi_to_priv_sd(wsi)->events,
226*1c60b9acSAndroid Build Coastguard Worker sock_accept_handler,
227*1c60b9acSAndroid Build Coastguard Worker wsi);
228*1c60b9acSAndroid Build Coastguard Worker
229*1c60b9acSAndroid Build Coastguard Worker io_sd(wsi, LWS_EV_START | LWS_EV_READ);
230*1c60b9acSAndroid Build Coastguard Worker
231*1c60b9acSAndroid Build Coastguard Worker return 0;
232*1c60b9acSAndroid Build Coastguard Worker }
233*1c60b9acSAndroid Build Coastguard Worker
234*1c60b9acSAndroid Build Coastguard Worker static int
elops_listen_init_sdevent(struct lws_dll2 * d,void * user)235*1c60b9acSAndroid Build Coastguard Worker elops_listen_init_sdevent(struct lws_dll2 *d, void *user)
236*1c60b9acSAndroid Build Coastguard Worker {
237*1c60b9acSAndroid Build Coastguard Worker struct lws *wsi = lws_container_of(d, struct lws, listen_list);
238*1c60b9acSAndroid Build Coastguard Worker
239*1c60b9acSAndroid Build Coastguard Worker if (init_vhost_listen_wsi_sd(wsi) == -1)
240*1c60b9acSAndroid Build Coastguard Worker return -1;
241*1c60b9acSAndroid Build Coastguard Worker
242*1c60b9acSAndroid Build Coastguard Worker return 0;
243*1c60b9acSAndroid Build Coastguard Worker }
244*1c60b9acSAndroid Build Coastguard Worker
245*1c60b9acSAndroid Build Coastguard Worker static int
init_pt_sd(struct lws_context * context,void * _loop,int tsi)246*1c60b9acSAndroid Build Coastguard Worker init_pt_sd(struct lws_context *context, void *_loop, int tsi)
247*1c60b9acSAndroid Build Coastguard Worker {
248*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt = &context->pt[tsi];
249*1c60b9acSAndroid Build Coastguard Worker struct lws_pt_eventlibs_sdevent *ptpriv = pt_to_priv_sd(pt);
250*1c60b9acSAndroid Build Coastguard Worker struct sd_event *loop = (struct sd_event *)_loop;
251*1c60b9acSAndroid Build Coastguard Worker int first = 1; /* first to create and initialize the loop */
252*1c60b9acSAndroid Build Coastguard Worker
253*1c60b9acSAndroid Build Coastguard Worker ptpriv->pt = pt;
254*1c60b9acSAndroid Build Coastguard Worker
255*1c60b9acSAndroid Build Coastguard Worker /* make sure we have an event loop */
256*1c60b9acSAndroid Build Coastguard Worker if (!ptpriv->io_loop) {
257*1c60b9acSAndroid Build Coastguard Worker if (!loop) {
258*1c60b9acSAndroid Build Coastguard Worker if (sd_event_default(&loop) < 0) {
259*1c60b9acSAndroid Build Coastguard Worker lwsl_cx_err(context, "sd_event_default failed");
260*1c60b9acSAndroid Build Coastguard Worker
261*1c60b9acSAndroid Build Coastguard Worker return -1;
262*1c60b9acSAndroid Build Coastguard Worker }
263*1c60b9acSAndroid Build Coastguard Worker pt->event_loop_foreign = 0;
264*1c60b9acSAndroid Build Coastguard Worker } else {
265*1c60b9acSAndroid Build Coastguard Worker sd_event_ref(loop);
266*1c60b9acSAndroid Build Coastguard Worker pt->event_loop_foreign = 1;
267*1c60b9acSAndroid Build Coastguard Worker }
268*1c60b9acSAndroid Build Coastguard Worker
269*1c60b9acSAndroid Build Coastguard Worker ptpriv->io_loop = loop;
270*1c60b9acSAndroid Build Coastguard Worker } else
271*1c60b9acSAndroid Build Coastguard Worker /*
272*1c60b9acSAndroid Build Coastguard Worker * If the loop was initialized before, we do not need to
273*1c60b9acSAndroid Build Coastguard Worker * do full initialization
274*1c60b9acSAndroid Build Coastguard Worker */
275*1c60b9acSAndroid Build Coastguard Worker first = 0;
276*1c60b9acSAndroid Build Coastguard Worker
277*1c60b9acSAndroid Build Coastguard Worker lws_vhost_foreach_listen_wsi(context, NULL, elops_listen_init_sdevent);
278*1c60b9acSAndroid Build Coastguard Worker
279*1c60b9acSAndroid Build Coastguard Worker if (first) {
280*1c60b9acSAndroid Build Coastguard Worker
281*1c60b9acSAndroid Build Coastguard Worker if (0 > sd_event_add_time(loop,
282*1c60b9acSAndroid Build Coastguard Worker &ptpriv->sultimer,
283*1c60b9acSAndroid Build Coastguard Worker CLOCK_MONOTONIC,
284*1c60b9acSAndroid Build Coastguard Worker UINT64_MAX,
285*1c60b9acSAndroid Build Coastguard Worker 0,
286*1c60b9acSAndroid Build Coastguard Worker sultimer_handler,
287*1c60b9acSAndroid Build Coastguard Worker (void*) pt
288*1c60b9acSAndroid Build Coastguard Worker ))
289*1c60b9acSAndroid Build Coastguard Worker return -1;
290*1c60b9acSAndroid Build Coastguard Worker
291*1c60b9acSAndroid Build Coastguard Worker if (0 > sd_event_add_time(loop,
292*1c60b9acSAndroid Build Coastguard Worker &ptpriv->idletimer,
293*1c60b9acSAndroid Build Coastguard Worker CLOCK_MONOTONIC,
294*1c60b9acSAndroid Build Coastguard Worker 0,
295*1c60b9acSAndroid Build Coastguard Worker 0,
296*1c60b9acSAndroid Build Coastguard Worker idle_handler,
297*1c60b9acSAndroid Build Coastguard Worker (void *)pt))
298*1c60b9acSAndroid Build Coastguard Worker return -1;
299*1c60b9acSAndroid Build Coastguard Worker
300*1c60b9acSAndroid Build Coastguard Worker sd_event_source_set_enabled(ptpriv->idletimer, SD_EVENT_ON);
301*1c60b9acSAndroid Build Coastguard Worker
302*1c60b9acSAndroid Build Coastguard Worker if (0 > sd_event_source_set_priority(ptpriv->idletimer,
303*1c60b9acSAndroid Build Coastguard Worker SD_EVENT_PRIORITY_IDLE))
304*1c60b9acSAndroid Build Coastguard Worker return -1;
305*1c60b9acSAndroid Build Coastguard Worker
306*1c60b9acSAndroid Build Coastguard Worker }
307*1c60b9acSAndroid Build Coastguard Worker
308*1c60b9acSAndroid Build Coastguard Worker return 0;
309*1c60b9acSAndroid Build Coastguard Worker }
310*1c60b9acSAndroid Build Coastguard Worker
311*1c60b9acSAndroid Build Coastguard Worker static void
wsi_destroy_sd(struct lws * wsi)312*1c60b9acSAndroid Build Coastguard Worker wsi_destroy_sd(struct lws *wsi)
313*1c60b9acSAndroid Build Coastguard Worker {
314*1c60b9acSAndroid Build Coastguard Worker if (!wsi)
315*1c60b9acSAndroid Build Coastguard Worker return;
316*1c60b9acSAndroid Build Coastguard Worker
317*1c60b9acSAndroid Build Coastguard Worker io_sd(wsi, LWS_EV_STOP | (LWS_EV_READ | LWS_EV_WRITE));
318*1c60b9acSAndroid Build Coastguard Worker
319*1c60b9acSAndroid Build Coastguard Worker if (wsi_to_priv_sd(wsi)->source) {
320*1c60b9acSAndroid Build Coastguard Worker sd_event_source_set_enabled(wsi_to_priv_sd(wsi)->source,
321*1c60b9acSAndroid Build Coastguard Worker SD_EVENT_OFF);
322*1c60b9acSAndroid Build Coastguard Worker sd_event_source_unref(wsi_to_priv_sd(wsi)->source);
323*1c60b9acSAndroid Build Coastguard Worker wsi_to_priv_sd(wsi)->source = NULL;
324*1c60b9acSAndroid Build Coastguard Worker }
325*1c60b9acSAndroid Build Coastguard Worker }
326*1c60b9acSAndroid Build Coastguard Worker
327*1c60b9acSAndroid Build Coastguard Worker static int
wsi_logical_close_sd(struct lws * wsi)328*1c60b9acSAndroid Build Coastguard Worker wsi_logical_close_sd(struct lws *wsi)
329*1c60b9acSAndroid Build Coastguard Worker {
330*1c60b9acSAndroid Build Coastguard Worker wsi_destroy_sd(wsi);
331*1c60b9acSAndroid Build Coastguard Worker
332*1c60b9acSAndroid Build Coastguard Worker return 0;
333*1c60b9acSAndroid Build Coastguard Worker }
334*1c60b9acSAndroid Build Coastguard Worker
335*1c60b9acSAndroid Build Coastguard Worker static int
sock_accept_sd(struct lws * wsi)336*1c60b9acSAndroid Build Coastguard Worker sock_accept_sd(struct lws *wsi)
337*1c60b9acSAndroid Build Coastguard Worker {
338*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
339*1c60b9acSAndroid Build Coastguard Worker
340*1c60b9acSAndroid Build Coastguard Worker if (wsi->role_ops->file_handle)
341*1c60b9acSAndroid Build Coastguard Worker sd_event_add_io(pt_to_priv_sd(pt)->io_loop,
342*1c60b9acSAndroid Build Coastguard Worker &wsi_to_priv_sd(wsi)->source,
343*1c60b9acSAndroid Build Coastguard Worker wsi->desc.filefd,
344*1c60b9acSAndroid Build Coastguard Worker wsi_to_priv_sd(wsi)->events,
345*1c60b9acSAndroid Build Coastguard Worker sock_accept_handler,
346*1c60b9acSAndroid Build Coastguard Worker wsi);
347*1c60b9acSAndroid Build Coastguard Worker else
348*1c60b9acSAndroid Build Coastguard Worker sd_event_add_io(pt_to_priv_sd(pt)->io_loop,
349*1c60b9acSAndroid Build Coastguard Worker &wsi_to_priv_sd(wsi)->source,
350*1c60b9acSAndroid Build Coastguard Worker wsi->desc.sockfd,
351*1c60b9acSAndroid Build Coastguard Worker wsi_to_priv_sd(wsi)->events,
352*1c60b9acSAndroid Build Coastguard Worker sock_accept_handler,
353*1c60b9acSAndroid Build Coastguard Worker wsi);
354*1c60b9acSAndroid Build Coastguard Worker
355*1c60b9acSAndroid Build Coastguard Worker return 0;
356*1c60b9acSAndroid Build Coastguard Worker }
357*1c60b9acSAndroid Build Coastguard Worker
358*1c60b9acSAndroid Build Coastguard Worker static void
run_pt_sd(struct lws_context * context,int tsi)359*1c60b9acSAndroid Build Coastguard Worker run_pt_sd(struct lws_context *context, int tsi)
360*1c60b9acSAndroid Build Coastguard Worker {
361*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt = &context->pt[tsi];
362*1c60b9acSAndroid Build Coastguard Worker struct lws_pt_eventlibs_sdevent *ptpriv = pt_to_priv_sd(pt);
363*1c60b9acSAndroid Build Coastguard Worker
364*1c60b9acSAndroid Build Coastguard Worker if (ptpriv->io_loop)
365*1c60b9acSAndroid Build Coastguard Worker sd_event_run(ptpriv->io_loop, (uint64_t) -1);
366*1c60b9acSAndroid Build Coastguard Worker }
367*1c60b9acSAndroid Build Coastguard Worker
368*1c60b9acSAndroid Build Coastguard Worker static int
elops_listen_destroy_sdevent(struct lws_dll2 * d,void * user)369*1c60b9acSAndroid Build Coastguard Worker elops_listen_destroy_sdevent(struct lws_dll2 *d, void *user)
370*1c60b9acSAndroid Build Coastguard Worker {
371*1c60b9acSAndroid Build Coastguard Worker struct lws *wsi = lws_container_of(d, struct lws, listen_list);
372*1c60b9acSAndroid Build Coastguard Worker
373*1c60b9acSAndroid Build Coastguard Worker wsi_logical_close_sd(wsi);
374*1c60b9acSAndroid Build Coastguard Worker
375*1c60b9acSAndroid Build Coastguard Worker return 0;
376*1c60b9acSAndroid Build Coastguard Worker }
377*1c60b9acSAndroid Build Coastguard Worker
378*1c60b9acSAndroid Build Coastguard Worker static void
destroy_pt_sd(struct lws_context * context,int tsi)379*1c60b9acSAndroid Build Coastguard Worker destroy_pt_sd(struct lws_context *context, int tsi)
380*1c60b9acSAndroid Build Coastguard Worker {
381*1c60b9acSAndroid Build Coastguard Worker struct lws_context_per_thread *pt = &context->pt[tsi];
382*1c60b9acSAndroid Build Coastguard Worker struct lws_pt_eventlibs_sdevent *ptpriv = pt_to_priv_sd(pt);
383*1c60b9acSAndroid Build Coastguard Worker
384*1c60b9acSAndroid Build Coastguard Worker lws_vhost_foreach_listen_wsi(context, NULL, elops_listen_destroy_sdevent);
385*1c60b9acSAndroid Build Coastguard Worker
386*1c60b9acSAndroid Build Coastguard Worker if (ptpriv->sultimer) {
387*1c60b9acSAndroid Build Coastguard Worker sd_event_source_set_enabled(ptpriv->sultimer,
388*1c60b9acSAndroid Build Coastguard Worker SD_EVENT_OFF);
389*1c60b9acSAndroid Build Coastguard Worker sd_event_source_unref(ptpriv->sultimer);
390*1c60b9acSAndroid Build Coastguard Worker ptpriv->sultimer = NULL;
391*1c60b9acSAndroid Build Coastguard Worker }
392*1c60b9acSAndroid Build Coastguard Worker
393*1c60b9acSAndroid Build Coastguard Worker if (ptpriv->idletimer) {
394*1c60b9acSAndroid Build Coastguard Worker sd_event_source_set_enabled(ptpriv->idletimer,
395*1c60b9acSAndroid Build Coastguard Worker SD_EVENT_OFF);
396*1c60b9acSAndroid Build Coastguard Worker sd_event_source_unref(ptpriv->idletimer);
397*1c60b9acSAndroid Build Coastguard Worker ptpriv->idletimer = NULL;
398*1c60b9acSAndroid Build Coastguard Worker }
399*1c60b9acSAndroid Build Coastguard Worker
400*1c60b9acSAndroid Build Coastguard Worker if (ptpriv->io_loop) {
401*1c60b9acSAndroid Build Coastguard Worker sd_event_unref(ptpriv->io_loop);
402*1c60b9acSAndroid Build Coastguard Worker ptpriv->io_loop = NULL;
403*1c60b9acSAndroid Build Coastguard Worker }
404*1c60b9acSAndroid Build Coastguard Worker }
405*1c60b9acSAndroid Build Coastguard Worker
406*1c60b9acSAndroid Build Coastguard Worker const struct lws_event_loop_ops event_loop_ops_sdevent = {
407*1c60b9acSAndroid Build Coastguard Worker .name = "sdevent",
408*1c60b9acSAndroid Build Coastguard Worker .init_context = NULL,
409*1c60b9acSAndroid Build Coastguard Worker .destroy_context1 = NULL,
410*1c60b9acSAndroid Build Coastguard Worker .destroy_context2 = NULL,
411*1c60b9acSAndroid Build Coastguard Worker .init_vhost_listen_wsi = init_vhost_listen_wsi_sd,
412*1c60b9acSAndroid Build Coastguard Worker .init_pt = init_pt_sd,
413*1c60b9acSAndroid Build Coastguard Worker .wsi_logical_close = wsi_logical_close_sd,
414*1c60b9acSAndroid Build Coastguard Worker .check_client_connect_ok = NULL,
415*1c60b9acSAndroid Build Coastguard Worker .close_handle_manually = NULL,
416*1c60b9acSAndroid Build Coastguard Worker .sock_accept = sock_accept_sd,
417*1c60b9acSAndroid Build Coastguard Worker .io = io_sd,
418*1c60b9acSAndroid Build Coastguard Worker .run_pt = run_pt_sd,
419*1c60b9acSAndroid Build Coastguard Worker .destroy_pt = destroy_pt_sd,
420*1c60b9acSAndroid Build Coastguard Worker .destroy_wsi = wsi_destroy_sd,
421*1c60b9acSAndroid Build Coastguard Worker
422*1c60b9acSAndroid Build Coastguard Worker .flags = 0,
423*1c60b9acSAndroid Build Coastguard Worker
424*1c60b9acSAndroid Build Coastguard Worker .evlib_size_ctx = 0,
425*1c60b9acSAndroid Build Coastguard Worker .evlib_size_pt = sizeof(struct lws_pt_eventlibs_sdevent),
426*1c60b9acSAndroid Build Coastguard Worker .evlib_size_vh = 0,
427*1c60b9acSAndroid Build Coastguard Worker .evlib_size_wsi = sizeof(struct lws_wsi_watcher_sdevent),
428*1c60b9acSAndroid Build Coastguard Worker };
429*1c60b9acSAndroid Build Coastguard Worker
430*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_EVLIB_PLUGINS)
431*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE
432*1c60b9acSAndroid Build Coastguard Worker #endif
433*1c60b9acSAndroid Build Coastguard Worker const lws_plugin_evlib_t evlib_sd = {
434*1c60b9acSAndroid Build Coastguard Worker .hdr = {
435*1c60b9acSAndroid Build Coastguard Worker "systemd event loop",
436*1c60b9acSAndroid Build Coastguard Worker "lws_evlib_plugin",
437*1c60b9acSAndroid Build Coastguard Worker LWS_BUILD_HASH,
438*1c60b9acSAndroid Build Coastguard Worker LWS_PLUGIN_API_MAGIC
439*1c60b9acSAndroid Build Coastguard Worker },
440*1c60b9acSAndroid Build Coastguard Worker
441*1c60b9acSAndroid Build Coastguard Worker .ops = &event_loop_ops_sdevent
442*1c60b9acSAndroid Build Coastguard Worker };
443