xref: /aosp_15_r20/external/libwebsockets/lib/roles/dbus/dbus.c (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
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 - 2019 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  * This role for wrapping dbus fds in a wsi + role is unusual in that the
25*1c60b9acSAndroid Build Coastguard Worker  * wsi it creates and binds to the role do not have control over the related fd
26*1c60b9acSAndroid Build Coastguard Worker  * lifecycle.  In fact dbus doesn't inform us directly about the lifecycle of
27*1c60b9acSAndroid Build Coastguard Worker  * the fds it wants to be managed by the lws event loop.
28*1c60b9acSAndroid Build Coastguard Worker  *
29*1c60b9acSAndroid Build Coastguard Worker  * What it does tell us is when it wants to wait on POLLOUT and / or POLLIN,
30*1c60b9acSAndroid Build Coastguard Worker  * and since it should stop any watchers before close, we take the approach to
31*1c60b9acSAndroid Build Coastguard Worker  * create a lightweight "shadow" wsi for any fd from dbus that has a POLLIN or
32*1c60b9acSAndroid Build Coastguard Worker  * POLLOUT wait active.  When the dbus fd asks to have no wait active, we
33*1c60b9acSAndroid Build Coastguard Worker  * destroy the wsi, since this is indistinguishable from dbus close path
34*1c60b9acSAndroid Build Coastguard Worker  * behaviour.  If it actually stays alive and later asks to wait again, well no
35*1c60b9acSAndroid Build Coastguard Worker  * worries we create a new shadow wsi until it looks like it is closing again.
36*1c60b9acSAndroid Build Coastguard Worker  */
37*1c60b9acSAndroid Build Coastguard Worker 
38*1c60b9acSAndroid Build Coastguard Worker #include <private-lib-core.h>
39*1c60b9acSAndroid Build Coastguard Worker 
40*1c60b9acSAndroid Build Coastguard Worker #include <libwebsockets/lws-dbus.h>
41*1c60b9acSAndroid Build Coastguard Worker 
42*1c60b9acSAndroid Build Coastguard Worker /*
43*1c60b9acSAndroid Build Coastguard Worker  * retreives existing or creates new shadow wsi for fd owned by dbus stuff.
44*1c60b9acSAndroid Build Coastguard Worker  *
45*1c60b9acSAndroid Build Coastguard Worker  * Requires context + vhost lock
46*1c60b9acSAndroid Build Coastguard Worker  */
47*1c60b9acSAndroid Build Coastguard Worker 
48*1c60b9acSAndroid Build Coastguard Worker static struct lws *
__lws_shadow_wsi(struct lws_dbus_ctx * ctx,DBusWatch * w,int fd,int create_ok)49*1c60b9acSAndroid Build Coastguard Worker __lws_shadow_wsi(struct lws_dbus_ctx *ctx, DBusWatch *w, int fd, int create_ok)
50*1c60b9acSAndroid Build Coastguard Worker {
51*1c60b9acSAndroid Build Coastguard Worker 	struct lws *wsi;
52*1c60b9acSAndroid Build Coastguard Worker 
53*1c60b9acSAndroid Build Coastguard Worker 	if (fd < 0 || fd >= (int)ctx->vh->context->fd_limit_per_thread) {
54*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: fd %d vs fds_count %d\n", __func__, fd,
55*1c60b9acSAndroid Build Coastguard Worker 				(int)ctx->vh->context->fd_limit_per_thread);
56*1c60b9acSAndroid Build Coastguard Worker 		assert(0);
57*1c60b9acSAndroid Build Coastguard Worker 
58*1c60b9acSAndroid Build Coastguard Worker 		return NULL;
59*1c60b9acSAndroid Build Coastguard Worker 	}
60*1c60b9acSAndroid Build Coastguard Worker 
61*1c60b9acSAndroid Build Coastguard Worker 	wsi = wsi_from_fd(ctx->vh->context, fd);
62*1c60b9acSAndroid Build Coastguard Worker 	if (wsi) {
63*1c60b9acSAndroid Build Coastguard Worker 		assert(wsi->opaque_parent_data == ctx);
64*1c60b9acSAndroid Build Coastguard Worker 
65*1c60b9acSAndroid Build Coastguard Worker 		return wsi;
66*1c60b9acSAndroid Build Coastguard Worker 	}
67*1c60b9acSAndroid Build Coastguard Worker 
68*1c60b9acSAndroid Build Coastguard Worker 	if (!create_ok)
69*1c60b9acSAndroid Build Coastguard Worker 		return NULL;
70*1c60b9acSAndroid Build Coastguard Worker 
71*1c60b9acSAndroid Build Coastguard Worker 	lws_context_assert_lock_held(wsi->a.context);
72*1c60b9acSAndroid Build Coastguard Worker 	lws_vhost_assert_lock_held(wsi->a.vhost);
73*1c60b9acSAndroid Build Coastguard Worker 
74*1c60b9acSAndroid Build Coastguard Worker 	/* requires context lock */
75*1c60b9acSAndroid Build Coastguard Worker 	wsi = __lws_wsi_create_with_role(ctx->vh->context, ctx->tsi, NULL,
76*1c60b9acSAndroid Build Coastguard Worker 						ctx->vh->lc.log_cx);
77*1c60b9acSAndroid Build Coastguard Worker 	if (wsi == NULL) {
78*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("Out of mem\n");
79*1c60b9acSAndroid Build Coastguard Worker 		return NULL;
80*1c60b9acSAndroid Build Coastguard Worker 	}
81*1c60b9acSAndroid Build Coastguard Worker 
82*1c60b9acSAndroid Build Coastguard Worker 	lwsl_info("%s: creating shadow wsi\n", __func__);
83*1c60b9acSAndroid Build Coastguard Worker 
84*1c60b9acSAndroid Build Coastguard Worker 	wsi->desc.sockfd = fd;
85*1c60b9acSAndroid Build Coastguard Worker 	lws_role_transition(wsi, 0, LRS_ESTABLISHED, &role_ops_dbus);
86*1c60b9acSAndroid Build Coastguard Worker 	wsi->a.protocol = ctx->vh->protocols;
87*1c60b9acSAndroid Build Coastguard Worker 	wsi->shadow = 1;
88*1c60b9acSAndroid Build Coastguard Worker 	wsi->opaque_parent_data = ctx;
89*1c60b9acSAndroid Build Coastguard Worker 	ctx->w[0] = w;
90*1c60b9acSAndroid Build Coastguard Worker 
91*1c60b9acSAndroid Build Coastguard Worker 	__lws_lc_tag(ctx->vh->context, &ctx->vh->context->lcg[LWSLCG_WSI],
92*1c60b9acSAndroid Build Coastguard Worker 		     &wsi->lc, "dbus|%s", ctx->vh->name);
93*1c60b9acSAndroid Build Coastguard Worker 
94*1c60b9acSAndroid Build Coastguard Worker 	lws_vhost_bind_wsi(ctx->vh, wsi);
95*1c60b9acSAndroid Build Coastguard Worker 	if (__insert_wsi_socket_into_fds(ctx->vh->context, wsi)) {
96*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("inserting wsi socket into fds failed\n");
97*1c60b9acSAndroid Build Coastguard Worker 		__lws_vhost_unbind_wsi(wsi); /* cx + vh lock */
98*1c60b9acSAndroid Build Coastguard Worker 		lws_free(wsi);
99*1c60b9acSAndroid Build Coastguard Worker 		return NULL;
100*1c60b9acSAndroid Build Coastguard Worker 	}
101*1c60b9acSAndroid Build Coastguard Worker 
102*1c60b9acSAndroid Build Coastguard Worker 	return wsi;
103*1c60b9acSAndroid Build Coastguard Worker }
104*1c60b9acSAndroid Build Coastguard Worker 
105*1c60b9acSAndroid Build Coastguard Worker /*
106*1c60b9acSAndroid Build Coastguard Worker  * Requires cx + vhost lock
107*1c60b9acSAndroid Build Coastguard Worker  */
108*1c60b9acSAndroid Build Coastguard Worker 
109*1c60b9acSAndroid Build Coastguard Worker static int
__lws_shadow_wsi_destroy(struct lws_dbus_ctx * ctx,struct lws * wsi)110*1c60b9acSAndroid Build Coastguard Worker __lws_shadow_wsi_destroy(struct lws_dbus_ctx *ctx, struct lws *wsi)
111*1c60b9acSAndroid Build Coastguard Worker {
112*1c60b9acSAndroid Build Coastguard Worker 	lwsl_info("%s: destroying shadow wsi\n", __func__);
113*1c60b9acSAndroid Build Coastguard Worker 
114*1c60b9acSAndroid Build Coastguard Worker 	lws_context_assert_lock_held(wsi->a.context);
115*1c60b9acSAndroid Build Coastguard Worker 	lws_vhost_assert_lock_held(wsi->a.vhost);
116*1c60b9acSAndroid Build Coastguard Worker 
117*1c60b9acSAndroid Build Coastguard Worker 	if (__remove_wsi_socket_from_fds(wsi)) {
118*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: unable to remove %d from fds\n", __func__,
119*1c60b9acSAndroid Build Coastguard Worker 				wsi->desc.sockfd);
120*1c60b9acSAndroid Build Coastguard Worker 
121*1c60b9acSAndroid Build Coastguard Worker 		return 1;
122*1c60b9acSAndroid Build Coastguard Worker 	}
123*1c60b9acSAndroid Build Coastguard Worker 
124*1c60b9acSAndroid Build Coastguard Worker 	__lws_vhost_unbind_wsi(wsi);
125*1c60b9acSAndroid Build Coastguard Worker 
126*1c60b9acSAndroid Build Coastguard Worker 	lws_free(wsi);
127*1c60b9acSAndroid Build Coastguard Worker 
128*1c60b9acSAndroid Build Coastguard Worker 	return 0;
129*1c60b9acSAndroid Build Coastguard Worker }
130*1c60b9acSAndroid Build Coastguard Worker 
131*1c60b9acSAndroid Build Coastguard Worker 
132*1c60b9acSAndroid Build Coastguard Worker static void
handle_dispatch_status(DBusConnection * c,DBusDispatchStatus s,void * data)133*1c60b9acSAndroid Build Coastguard Worker handle_dispatch_status(DBusConnection *c, DBusDispatchStatus s, void *data)
134*1c60b9acSAndroid Build Coastguard Worker {
135*1c60b9acSAndroid Build Coastguard Worker 	lwsl_info("%s: new dbus dispatch status: %d\n", __func__, s);
136*1c60b9acSAndroid Build Coastguard Worker }
137*1c60b9acSAndroid Build Coastguard Worker 
138*1c60b9acSAndroid Build Coastguard Worker /*
139*1c60b9acSAndroid Build Coastguard Worker  * These are complicated by the fact libdbus can have two separate DBusWatch
140*1c60b9acSAndroid Build Coastguard Worker  * objects for the same fd, to control watching POLLIN and POLLOUT individually.
141*1c60b9acSAndroid Build Coastguard Worker  *
142*1c60b9acSAndroid Build Coastguard Worker  * However we will actually watch using poll(), where the unit is the fd, and
143*1c60b9acSAndroid Build Coastguard Worker  * it has a unified events field with just POLLIN / POLLOUT flags.
144*1c60b9acSAndroid Build Coastguard Worker  *
145*1c60b9acSAndroid Build Coastguard Worker  * So we have to be prepared for one or two watchers coming in any order.
146*1c60b9acSAndroid Build Coastguard Worker  */
147*1c60b9acSAndroid Build Coastguard Worker 
148*1c60b9acSAndroid Build Coastguard Worker static dbus_bool_t
lws_dbus_add_watch(DBusWatch * w,void * data)149*1c60b9acSAndroid Build Coastguard Worker lws_dbus_add_watch(DBusWatch *w, void *data)
150*1c60b9acSAndroid Build Coastguard Worker {
151*1c60b9acSAndroid Build Coastguard Worker 	struct lws_dbus_ctx *ctx = (struct lws_dbus_ctx *)data;
152*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context_per_thread *pt = &ctx->vh->context->pt[ctx->tsi];
153*1c60b9acSAndroid Build Coastguard Worker 	unsigned int flags = 0, lws_flags = 0;
154*1c60b9acSAndroid Build Coastguard Worker 	struct lws *wsi;
155*1c60b9acSAndroid Build Coastguard Worker 	int n;
156*1c60b9acSAndroid Build Coastguard Worker 
157*1c60b9acSAndroid Build Coastguard Worker 	lws_context_lock(pt->context, __func__);
158*1c60b9acSAndroid Build Coastguard Worker 	lws_pt_lock(pt, __func__);
159*1c60b9acSAndroid Build Coastguard Worker 
160*1c60b9acSAndroid Build Coastguard Worker 	wsi = __lws_shadow_wsi(ctx, w, dbus_watch_get_unix_fd(w), 1);
161*1c60b9acSAndroid Build Coastguard Worker 	if (!wsi) {
162*1c60b9acSAndroid Build Coastguard Worker 		lws_pt_unlock(pt);
163*1c60b9acSAndroid Build Coastguard Worker 		lws_context_unlock(pt->context);
164*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: unable to get wsi\n", __func__);
165*1c60b9acSAndroid Build Coastguard Worker 
166*1c60b9acSAndroid Build Coastguard Worker 		return FALSE;
167*1c60b9acSAndroid Build Coastguard Worker 	}
168*1c60b9acSAndroid Build Coastguard Worker 
169*1c60b9acSAndroid Build Coastguard Worker 	for (n = 0; n < (int)LWS_ARRAY_SIZE(ctx->w); n++)
170*1c60b9acSAndroid Build Coastguard Worker 		if (w == ctx->w[n])
171*1c60b9acSAndroid Build Coastguard Worker 			break;
172*1c60b9acSAndroid Build Coastguard Worker 
173*1c60b9acSAndroid Build Coastguard Worker 	if (n == (int)LWS_ARRAY_SIZE(ctx->w))
174*1c60b9acSAndroid Build Coastguard Worker 		for (n = 0; n < (int)LWS_ARRAY_SIZE(ctx->w); n++)
175*1c60b9acSAndroid Build Coastguard Worker 			if (!ctx->w[n]) {
176*1c60b9acSAndroid Build Coastguard Worker 				ctx->w[n] = w;
177*1c60b9acSAndroid Build Coastguard Worker 				break;
178*1c60b9acSAndroid Build Coastguard Worker 			}
179*1c60b9acSAndroid Build Coastguard Worker 
180*1c60b9acSAndroid Build Coastguard Worker 	for (n = 0; n < (int)LWS_ARRAY_SIZE(ctx->w); n++)
181*1c60b9acSAndroid Build Coastguard Worker 		if (ctx->w[n] && dbus_watch_get_enabled(ctx->w[n]))
182*1c60b9acSAndroid Build Coastguard Worker 			flags |= dbus_watch_get_flags(ctx->w[n]);
183*1c60b9acSAndroid Build Coastguard Worker 
184*1c60b9acSAndroid Build Coastguard Worker 	if (flags & DBUS_WATCH_READABLE)
185*1c60b9acSAndroid Build Coastguard Worker 		lws_flags |= LWS_POLLIN;
186*1c60b9acSAndroid Build Coastguard Worker 	if (flags & DBUS_WATCH_WRITABLE)
187*1c60b9acSAndroid Build Coastguard Worker 		lws_flags |= LWS_POLLOUT;
188*1c60b9acSAndroid Build Coastguard Worker 
189*1c60b9acSAndroid Build Coastguard Worker 	lwsl_info("%s: %s: %p, fd %d, data %p, fl %d\n", __func__,
190*1c60b9acSAndroid Build Coastguard Worker 		  lws_wsi_tag(wsi), w, dbus_watch_get_unix_fd(w),
191*1c60b9acSAndroid Build Coastguard Worker 		  data, lws_flags);
192*1c60b9acSAndroid Build Coastguard Worker 
193*1c60b9acSAndroid Build Coastguard Worker 	if (lws_flags)
194*1c60b9acSAndroid Build Coastguard Worker 		__lws_change_pollfd(wsi, 0, (int)lws_flags);
195*1c60b9acSAndroid Build Coastguard Worker 
196*1c60b9acSAndroid Build Coastguard Worker 	lws_pt_unlock(pt);
197*1c60b9acSAndroid Build Coastguard Worker 	lws_context_unlock(pt->context);
198*1c60b9acSAndroid Build Coastguard Worker 
199*1c60b9acSAndroid Build Coastguard Worker 	return TRUE;
200*1c60b9acSAndroid Build Coastguard Worker }
201*1c60b9acSAndroid Build Coastguard Worker 
202*1c60b9acSAndroid Build Coastguard Worker /* cx + vh lock */
203*1c60b9acSAndroid Build Coastguard Worker static int
__check_destroy_shadow_wsi(struct lws_dbus_ctx * ctx,struct lws * wsi)204*1c60b9acSAndroid Build Coastguard Worker __check_destroy_shadow_wsi(struct lws_dbus_ctx *ctx, struct lws *wsi)
205*1c60b9acSAndroid Build Coastguard Worker {
206*1c60b9acSAndroid Build Coastguard Worker 	int n;
207*1c60b9acSAndroid Build Coastguard Worker 
208*1c60b9acSAndroid Build Coastguard Worker 	if (!wsi)
209*1c60b9acSAndroid Build Coastguard Worker 		return 0;
210*1c60b9acSAndroid Build Coastguard Worker 
211*1c60b9acSAndroid Build Coastguard Worker 	for (n = 0; n < (int)LWS_ARRAY_SIZE(ctx->w); n++)
212*1c60b9acSAndroid Build Coastguard Worker 		if (ctx->w[n])
213*1c60b9acSAndroid Build Coastguard Worker 			return 0;
214*1c60b9acSAndroid Build Coastguard Worker 
215*1c60b9acSAndroid Build Coastguard Worker 	__lws_shadow_wsi_destroy(ctx, wsi);
216*1c60b9acSAndroid Build Coastguard Worker 
217*1c60b9acSAndroid Build Coastguard Worker 	if (!ctx->conn || !ctx->hup || ctx->timeouts)
218*1c60b9acSAndroid Build Coastguard Worker 		return 0;
219*1c60b9acSAndroid Build Coastguard Worker 
220*1c60b9acSAndroid Build Coastguard Worker 	if (dbus_connection_get_dispatch_status(ctx->conn) ==
221*1c60b9acSAndroid Build Coastguard Worker 						     DBUS_DISPATCH_DATA_REMAINS)
222*1c60b9acSAndroid Build Coastguard Worker 		return 0;
223*1c60b9acSAndroid Build Coastguard Worker 
224*1c60b9acSAndroid Build Coastguard Worker 	if (ctx->cb_closing)
225*1c60b9acSAndroid Build Coastguard Worker 		ctx->cb_closing(ctx);
226*1c60b9acSAndroid Build Coastguard Worker 
227*1c60b9acSAndroid Build Coastguard Worker 	return 1;
228*1c60b9acSAndroid Build Coastguard Worker }
229*1c60b9acSAndroid Build Coastguard Worker 
230*1c60b9acSAndroid Build Coastguard Worker static void
lws_dbus_remove_watch(DBusWatch * w,void * data)231*1c60b9acSAndroid Build Coastguard Worker lws_dbus_remove_watch(DBusWatch *w, void *data)
232*1c60b9acSAndroid Build Coastguard Worker {
233*1c60b9acSAndroid Build Coastguard Worker 	struct lws_dbus_ctx *ctx = (struct lws_dbus_ctx *)data;
234*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context_per_thread *pt = &ctx->vh->context->pt[ctx->tsi];
235*1c60b9acSAndroid Build Coastguard Worker 	unsigned int flags = 0, lws_flags = 0;
236*1c60b9acSAndroid Build Coastguard Worker 	struct lws *wsi;
237*1c60b9acSAndroid Build Coastguard Worker 	int n;
238*1c60b9acSAndroid Build Coastguard Worker 
239*1c60b9acSAndroid Build Coastguard Worker 	lws_context_lock(pt->context, __func__);
240*1c60b9acSAndroid Build Coastguard Worker 	lws_pt_lock(pt, __func__);
241*1c60b9acSAndroid Build Coastguard Worker 
242*1c60b9acSAndroid Build Coastguard Worker 	wsi = __lws_shadow_wsi(ctx, w, dbus_watch_get_unix_fd(w), 0);
243*1c60b9acSAndroid Build Coastguard Worker 	if (!wsi)
244*1c60b9acSAndroid Build Coastguard Worker 		goto bail;
245*1c60b9acSAndroid Build Coastguard Worker 
246*1c60b9acSAndroid Build Coastguard Worker 	for (n = 0; n < (int)LWS_ARRAY_SIZE(ctx->w); n++)
247*1c60b9acSAndroid Build Coastguard Worker 		if (w == ctx->w[n]) {
248*1c60b9acSAndroid Build Coastguard Worker 			ctx->w[n] = NULL;
249*1c60b9acSAndroid Build Coastguard Worker 			break;
250*1c60b9acSAndroid Build Coastguard Worker 		}
251*1c60b9acSAndroid Build Coastguard Worker 
252*1c60b9acSAndroid Build Coastguard Worker 	for (n = 0; n < (int)LWS_ARRAY_SIZE(ctx->w); n++)
253*1c60b9acSAndroid Build Coastguard Worker 		if (ctx->w[n])
254*1c60b9acSAndroid Build Coastguard Worker 			flags |= dbus_watch_get_flags(ctx->w[n]);
255*1c60b9acSAndroid Build Coastguard Worker 
256*1c60b9acSAndroid Build Coastguard Worker 	if ((~flags) & DBUS_WATCH_READABLE)
257*1c60b9acSAndroid Build Coastguard Worker 		lws_flags |= LWS_POLLIN;
258*1c60b9acSAndroid Build Coastguard Worker 	if ((~flags) & DBUS_WATCH_WRITABLE)
259*1c60b9acSAndroid Build Coastguard Worker 		lws_flags |= LWS_POLLOUT;
260*1c60b9acSAndroid Build Coastguard Worker 
261*1c60b9acSAndroid Build Coastguard Worker 	lwsl_info("%s: %p, fd %d, data %p, clearing lws flags %d\n",
262*1c60b9acSAndroid Build Coastguard Worker 		  __func__, w, dbus_watch_get_unix_fd(w),
263*1c60b9acSAndroid Build Coastguard Worker 		  data, lws_flags);
264*1c60b9acSAndroid Build Coastguard Worker 
265*1c60b9acSAndroid Build Coastguard Worker 	__lws_change_pollfd(wsi, (int)lws_flags, 0);
266*1c60b9acSAndroid Build Coastguard Worker 
267*1c60b9acSAndroid Build Coastguard Worker bail:
268*1c60b9acSAndroid Build Coastguard Worker 	lws_pt_unlock(pt);
269*1c60b9acSAndroid Build Coastguard Worker 	lws_context_unlock(pt->context);
270*1c60b9acSAndroid Build Coastguard Worker }
271*1c60b9acSAndroid Build Coastguard Worker 
272*1c60b9acSAndroid Build Coastguard Worker static void
lws_dbus_toggle_watch(DBusWatch * w,void * data)273*1c60b9acSAndroid Build Coastguard Worker lws_dbus_toggle_watch(DBusWatch *w, void *data)
274*1c60b9acSAndroid Build Coastguard Worker {
275*1c60b9acSAndroid Build Coastguard Worker 	if (dbus_watch_get_enabled(w))
276*1c60b9acSAndroid Build Coastguard Worker 		lws_dbus_add_watch(w, data);
277*1c60b9acSAndroid Build Coastguard Worker 	else
278*1c60b9acSAndroid Build Coastguard Worker 		lws_dbus_remove_watch(w, data);
279*1c60b9acSAndroid Build Coastguard Worker }
280*1c60b9acSAndroid Build Coastguard Worker 
281*1c60b9acSAndroid Build Coastguard Worker static void
lws_dbus_sul_cb(lws_sorted_usec_list_t * sul)282*1c60b9acSAndroid Build Coastguard Worker lws_dbus_sul_cb(lws_sorted_usec_list_t *sul)
283*1c60b9acSAndroid Build Coastguard Worker {
284*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context_per_thread *pt = lws_container_of(sul,
285*1c60b9acSAndroid Build Coastguard Worker 				struct lws_context_per_thread, dbus.sul);
286*1c60b9acSAndroid Build Coastguard Worker 
287*1c60b9acSAndroid Build Coastguard Worker 	lws_start_foreach_dll_safe(struct lws_dll2 *, rdt, nx,
288*1c60b9acSAndroid Build Coastguard Worker 			 lws_dll2_get_head(&pt->dbus.timer_list_owner)) {
289*1c60b9acSAndroid Build Coastguard Worker 		struct lws_role_dbus_timer *r = lws_container_of(rdt,
290*1c60b9acSAndroid Build Coastguard Worker 					struct lws_role_dbus_timer, timer_list);
291*1c60b9acSAndroid Build Coastguard Worker 
292*1c60b9acSAndroid Build Coastguard Worker 		if (time(NULL) > r->fire) {
293*1c60b9acSAndroid Build Coastguard Worker 			lwsl_notice("%s: firing timer\n", __func__);
294*1c60b9acSAndroid Build Coastguard Worker 			dbus_timeout_handle(r->data);
295*1c60b9acSAndroid Build Coastguard Worker 			lws_dll2_remove(rdt);
296*1c60b9acSAndroid Build Coastguard Worker 			lws_free(rdt);
297*1c60b9acSAndroid Build Coastguard Worker 		}
298*1c60b9acSAndroid Build Coastguard Worker 	} lws_end_foreach_dll_safe(rdt, nx);
299*1c60b9acSAndroid Build Coastguard Worker 
300*1c60b9acSAndroid Build Coastguard Worker 	if (pt->dbus.timer_list_owner.count)
301*1c60b9acSAndroid Build Coastguard Worker 		lws_sul_schedule(pt->context, pt->tid, &pt->dbus.sul,
302*1c60b9acSAndroid Build Coastguard Worker 				 lws_dbus_sul_cb, 3 * LWS_US_PER_SEC);
303*1c60b9acSAndroid Build Coastguard Worker }
304*1c60b9acSAndroid Build Coastguard Worker 
305*1c60b9acSAndroid Build Coastguard Worker static dbus_bool_t
lws_dbus_add_timeout(DBusTimeout * t,void * data)306*1c60b9acSAndroid Build Coastguard Worker lws_dbus_add_timeout(DBusTimeout *t, void *data)
307*1c60b9acSAndroid Build Coastguard Worker {
308*1c60b9acSAndroid Build Coastguard Worker 	struct lws_dbus_ctx *ctx = (struct lws_dbus_ctx *)data;
309*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context_per_thread *pt = &ctx->vh->context->pt[ctx->tsi];
310*1c60b9acSAndroid Build Coastguard Worker 	int ms = dbus_timeout_get_interval(t);
311*1c60b9acSAndroid Build Coastguard Worker 	struct lws_role_dbus_timer *dbt;
312*1c60b9acSAndroid Build Coastguard Worker 	time_t ti = time(NULL);
313*1c60b9acSAndroid Build Coastguard Worker 
314*1c60b9acSAndroid Build Coastguard Worker 	if (!dbus_timeout_get_enabled(t))
315*1c60b9acSAndroid Build Coastguard Worker 		return TRUE;
316*1c60b9acSAndroid Build Coastguard Worker 
317*1c60b9acSAndroid Build Coastguard Worker 	if (ms < 1000)
318*1c60b9acSAndroid Build Coastguard Worker 		ms = 1000;
319*1c60b9acSAndroid Build Coastguard Worker 
320*1c60b9acSAndroid Build Coastguard Worker 	dbt = lws_malloc(sizeof(*dbt), "dbus timer");
321*1c60b9acSAndroid Build Coastguard Worker 	if (!dbt)
322*1c60b9acSAndroid Build Coastguard Worker 		return FALSE;
323*1c60b9acSAndroid Build Coastguard Worker 
324*1c60b9acSAndroid Build Coastguard Worker 	lwsl_info("%s: adding timeout %dms\n", __func__,
325*1c60b9acSAndroid Build Coastguard Worker 			dbus_timeout_get_interval(t));
326*1c60b9acSAndroid Build Coastguard Worker 
327*1c60b9acSAndroid Build Coastguard Worker 	dbt->data = t;
328*1c60b9acSAndroid Build Coastguard Worker 	dbt->fire = ti + (ms < 1000);
329*1c60b9acSAndroid Build Coastguard Worker 	dbt->timer_list.prev = NULL;
330*1c60b9acSAndroid Build Coastguard Worker 	dbt->timer_list.next = NULL;
331*1c60b9acSAndroid Build Coastguard Worker 	dbt->timer_list.owner = NULL;
332*1c60b9acSAndroid Build Coastguard Worker 	lws_dll2_add_head(&dbt->timer_list, &pt->dbus.timer_list_owner);
333*1c60b9acSAndroid Build Coastguard Worker 
334*1c60b9acSAndroid Build Coastguard Worker 	if (!pt->dbus.sul.list.owner)
335*1c60b9acSAndroid Build Coastguard Worker 		lws_sul_schedule(pt->context, pt->tid, &pt->dbus.sul,
336*1c60b9acSAndroid Build Coastguard Worker 				 lws_dbus_sul_cb, 3 * LWS_US_PER_SEC);
337*1c60b9acSAndroid Build Coastguard Worker 
338*1c60b9acSAndroid Build Coastguard Worker 	ctx->timeouts++;
339*1c60b9acSAndroid Build Coastguard Worker 
340*1c60b9acSAndroid Build Coastguard Worker 	return TRUE;
341*1c60b9acSAndroid Build Coastguard Worker }
342*1c60b9acSAndroid Build Coastguard Worker 
343*1c60b9acSAndroid Build Coastguard Worker static void
lws_dbus_remove_timeout(DBusTimeout * t,void * data)344*1c60b9acSAndroid Build Coastguard Worker lws_dbus_remove_timeout(DBusTimeout *t, void *data)
345*1c60b9acSAndroid Build Coastguard Worker {
346*1c60b9acSAndroid Build Coastguard Worker 	struct lws_dbus_ctx *ctx = (struct lws_dbus_ctx *)data;
347*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context_per_thread *pt = &ctx->vh->context->pt[ctx->tsi];
348*1c60b9acSAndroid Build Coastguard Worker 
349*1c60b9acSAndroid Build Coastguard Worker 	lwsl_info("%s: t %p, data %p\n", __func__, t, data);
350*1c60b9acSAndroid Build Coastguard Worker 
351*1c60b9acSAndroid Build Coastguard Worker 	lws_start_foreach_dll_safe(struct lws_dll2 *, rdt, nx,
352*1c60b9acSAndroid Build Coastguard Worker 				lws_dll2_get_head(&pt->dbus.timer_list_owner)) {
353*1c60b9acSAndroid Build Coastguard Worker 		struct lws_role_dbus_timer *r = lws_container_of(rdt,
354*1c60b9acSAndroid Build Coastguard Worker 					struct lws_role_dbus_timer, timer_list);
355*1c60b9acSAndroid Build Coastguard Worker 		if (t == r->data) {
356*1c60b9acSAndroid Build Coastguard Worker 			lws_dll2_remove(rdt);
357*1c60b9acSAndroid Build Coastguard Worker 			lws_free(rdt);
358*1c60b9acSAndroid Build Coastguard Worker 			ctx->timeouts--;
359*1c60b9acSAndroid Build Coastguard Worker 			break;
360*1c60b9acSAndroid Build Coastguard Worker 		}
361*1c60b9acSAndroid Build Coastguard Worker 	} lws_end_foreach_dll_safe(rdt, nx);
362*1c60b9acSAndroid Build Coastguard Worker 
363*1c60b9acSAndroid Build Coastguard Worker 	if (!pt->dbus.timer_list_owner.count)
364*1c60b9acSAndroid Build Coastguard Worker 		lws_sul_cancel(&pt->dbus.sul);
365*1c60b9acSAndroid Build Coastguard Worker }
366*1c60b9acSAndroid Build Coastguard Worker 
367*1c60b9acSAndroid Build Coastguard Worker static void
lws_dbus_toggle_timeout(DBusTimeout * t,void * data)368*1c60b9acSAndroid Build Coastguard Worker lws_dbus_toggle_timeout(DBusTimeout *t, void *data)
369*1c60b9acSAndroid Build Coastguard Worker {
370*1c60b9acSAndroid Build Coastguard Worker 	if (dbus_timeout_get_enabled(t))
371*1c60b9acSAndroid Build Coastguard Worker 		lws_dbus_add_timeout(t, data);
372*1c60b9acSAndroid Build Coastguard Worker 	else
373*1c60b9acSAndroid Build Coastguard Worker 		lws_dbus_remove_timeout(t, data);
374*1c60b9acSAndroid Build Coastguard Worker }
375*1c60b9acSAndroid Build Coastguard Worker 
376*1c60b9acSAndroid Build Coastguard Worker /*
377*1c60b9acSAndroid Build Coastguard Worker  * This sets up a connection along the same lines as
378*1c60b9acSAndroid Build Coastguard Worker  * dbus_connection_setup_with_g_main(), but for using the lws event loop.
379*1c60b9acSAndroid Build Coastguard Worker  */
380*1c60b9acSAndroid Build Coastguard Worker 
381*1c60b9acSAndroid Build Coastguard Worker int
lws_dbus_connection_setup(struct lws_dbus_ctx * ctx,DBusConnection * conn,lws_dbus_closing_t cb_closing)382*1c60b9acSAndroid Build Coastguard Worker lws_dbus_connection_setup(struct lws_dbus_ctx *ctx, DBusConnection *conn,
383*1c60b9acSAndroid Build Coastguard Worker 			  lws_dbus_closing_t cb_closing)
384*1c60b9acSAndroid Build Coastguard Worker {
385*1c60b9acSAndroid Build Coastguard Worker 	int n;
386*1c60b9acSAndroid Build Coastguard Worker 
387*1c60b9acSAndroid Build Coastguard Worker 	ctx->conn = conn;
388*1c60b9acSAndroid Build Coastguard Worker 	ctx->cb_closing = cb_closing;
389*1c60b9acSAndroid Build Coastguard Worker 	ctx->hup = 0;
390*1c60b9acSAndroid Build Coastguard Worker 	ctx->timeouts = 0;
391*1c60b9acSAndroid Build Coastguard Worker 	for (n = 0; n < (int)LWS_ARRAY_SIZE(ctx->w); n++)
392*1c60b9acSAndroid Build Coastguard Worker 		ctx->w[n] = NULL;
393*1c60b9acSAndroid Build Coastguard Worker 
394*1c60b9acSAndroid Build Coastguard Worker 	if (!dbus_connection_set_watch_functions(conn, lws_dbus_add_watch,
395*1c60b9acSAndroid Build Coastguard Worker 						 lws_dbus_remove_watch,
396*1c60b9acSAndroid Build Coastguard Worker 						 lws_dbus_toggle_watch,
397*1c60b9acSAndroid Build Coastguard Worker 						 ctx, NULL)) {
398*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: dbus_connection_set_watch_functions fail\n",
399*1c60b9acSAndroid Build Coastguard Worker 			 __func__);
400*1c60b9acSAndroid Build Coastguard Worker 		return 1;
401*1c60b9acSAndroid Build Coastguard Worker 	}
402*1c60b9acSAndroid Build Coastguard Worker 
403*1c60b9acSAndroid Build Coastguard Worker 	if (!dbus_connection_set_timeout_functions(conn,
404*1c60b9acSAndroid Build Coastguard Worker 						   lws_dbus_add_timeout,
405*1c60b9acSAndroid Build Coastguard Worker 						   lws_dbus_remove_timeout,
406*1c60b9acSAndroid Build Coastguard Worker 						   lws_dbus_toggle_timeout,
407*1c60b9acSAndroid Build Coastguard Worker 						   ctx, NULL)) {
408*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: dbus_connection_set_timeout_functions fail\n",
409*1c60b9acSAndroid Build Coastguard Worker 			 __func__);
410*1c60b9acSAndroid Build Coastguard Worker 		return 1;
411*1c60b9acSAndroid Build Coastguard Worker 	}
412*1c60b9acSAndroid Build Coastguard Worker 
413*1c60b9acSAndroid Build Coastguard Worker 	dbus_connection_set_dispatch_status_function(conn,
414*1c60b9acSAndroid Build Coastguard Worker 						     handle_dispatch_status,
415*1c60b9acSAndroid Build Coastguard Worker 						     ctx, NULL);
416*1c60b9acSAndroid Build Coastguard Worker 
417*1c60b9acSAndroid Build Coastguard Worker 	return 0;
418*1c60b9acSAndroid Build Coastguard Worker }
419*1c60b9acSAndroid Build Coastguard Worker 
420*1c60b9acSAndroid Build Coastguard Worker /*
421*1c60b9acSAndroid Build Coastguard Worker  * This wraps dbus_server_listen(), additionally taking care of the event loop
422*1c60b9acSAndroid Build Coastguard Worker  * -related setups.
423*1c60b9acSAndroid Build Coastguard Worker  */
424*1c60b9acSAndroid Build Coastguard Worker 
425*1c60b9acSAndroid Build Coastguard Worker DBusServer *
lws_dbus_server_listen(struct lws_dbus_ctx * ctx,const char * ads,DBusError * e,DBusNewConnectionFunction new_conn)426*1c60b9acSAndroid Build Coastguard Worker lws_dbus_server_listen(struct lws_dbus_ctx *ctx, const char *ads, DBusError *e,
427*1c60b9acSAndroid Build Coastguard Worker 		       DBusNewConnectionFunction new_conn)
428*1c60b9acSAndroid Build Coastguard Worker {
429*1c60b9acSAndroid Build Coastguard Worker 	ctx->cb_closing = NULL;
430*1c60b9acSAndroid Build Coastguard Worker 	ctx->hup = 0;
431*1c60b9acSAndroid Build Coastguard Worker 	ctx->timeouts = 0;
432*1c60b9acSAndroid Build Coastguard Worker 
433*1c60b9acSAndroid Build Coastguard Worker 	ctx->dbs = dbus_server_listen(ads, e);
434*1c60b9acSAndroid Build Coastguard Worker 	if (!ctx->dbs)
435*1c60b9acSAndroid Build Coastguard Worker 		return NULL;
436*1c60b9acSAndroid Build Coastguard Worker 
437*1c60b9acSAndroid Build Coastguard Worker 	dbus_server_set_new_connection_function(ctx->dbs, new_conn, ctx, NULL);
438*1c60b9acSAndroid Build Coastguard Worker 
439*1c60b9acSAndroid Build Coastguard Worker 	if (!dbus_server_set_watch_functions(ctx->dbs, lws_dbus_add_watch,
440*1c60b9acSAndroid Build Coastguard Worker 					     lws_dbus_remove_watch,
441*1c60b9acSAndroid Build Coastguard Worker 					     lws_dbus_toggle_watch,
442*1c60b9acSAndroid Build Coastguard Worker 					     ctx, NULL)) {
443*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: dbus_connection_set_watch_functions fail\n",
444*1c60b9acSAndroid Build Coastguard Worker 			 __func__);
445*1c60b9acSAndroid Build Coastguard Worker 		goto bail;
446*1c60b9acSAndroid Build Coastguard Worker 	}
447*1c60b9acSAndroid Build Coastguard Worker 
448*1c60b9acSAndroid Build Coastguard Worker 	if (!dbus_server_set_timeout_functions(ctx->dbs, lws_dbus_add_timeout,
449*1c60b9acSAndroid Build Coastguard Worker 					       lws_dbus_remove_timeout,
450*1c60b9acSAndroid Build Coastguard Worker 					       lws_dbus_toggle_timeout,
451*1c60b9acSAndroid Build Coastguard Worker 					       ctx, NULL)) {
452*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: dbus_connection_set_timeout_functions fail\n",
453*1c60b9acSAndroid Build Coastguard Worker 			 __func__);
454*1c60b9acSAndroid Build Coastguard Worker 		goto bail;
455*1c60b9acSAndroid Build Coastguard Worker 	}
456*1c60b9acSAndroid Build Coastguard Worker 
457*1c60b9acSAndroid Build Coastguard Worker 	return ctx->dbs;
458*1c60b9acSAndroid Build Coastguard Worker 
459*1c60b9acSAndroid Build Coastguard Worker bail:
460*1c60b9acSAndroid Build Coastguard Worker 	dbus_server_disconnect(ctx->dbs);
461*1c60b9acSAndroid Build Coastguard Worker 	dbus_server_unref(ctx->dbs);
462*1c60b9acSAndroid Build Coastguard Worker 
463*1c60b9acSAndroid Build Coastguard Worker 	return NULL;
464*1c60b9acSAndroid Build Coastguard Worker }
465*1c60b9acSAndroid Build Coastguard Worker 
466*1c60b9acSAndroid Build Coastguard Worker 
467*1c60b9acSAndroid Build Coastguard Worker /*
468*1c60b9acSAndroid Build Coastguard Worker  * There shouldn't be a race here with watcher removal and poll wait, because
469*1c60b9acSAndroid Build Coastguard Worker  * everything including the dbus activity is serialized in one event loop.
470*1c60b9acSAndroid Build Coastguard Worker  *
471*1c60b9acSAndroid Build Coastguard Worker  * If it removes the watcher and we remove the wsi and fd entry before this,
472*1c60b9acSAndroid Build Coastguard Worker  * actually we can no longer map the fd to this invalidated wsi pointer to call
473*1c60b9acSAndroid Build Coastguard Worker  * this.
474*1c60b9acSAndroid Build Coastguard Worker  */
475*1c60b9acSAndroid Build Coastguard Worker 
476*1c60b9acSAndroid Build Coastguard Worker static int
rops_handle_POLLIN_dbus(struct lws_context_per_thread * pt,struct lws * wsi,struct lws_pollfd * pollfd)477*1c60b9acSAndroid Build Coastguard Worker rops_handle_POLLIN_dbus(struct lws_context_per_thread *pt, struct lws *wsi,
478*1c60b9acSAndroid Build Coastguard Worker 			struct lws_pollfd *pollfd)
479*1c60b9acSAndroid Build Coastguard Worker {
480*1c60b9acSAndroid Build Coastguard Worker 	struct lws_dbus_ctx *ctx =
481*1c60b9acSAndroid Build Coastguard Worker 			(struct lws_dbus_ctx *)wsi->opaque_parent_data;
482*1c60b9acSAndroid Build Coastguard Worker 	unsigned int flags = 0;
483*1c60b9acSAndroid Build Coastguard Worker 	int n;
484*1c60b9acSAndroid Build Coastguard Worker 
485*1c60b9acSAndroid Build Coastguard Worker 	if (pollfd->revents & LWS_POLLIN)
486*1c60b9acSAndroid Build Coastguard Worker 		flags |= DBUS_WATCH_READABLE;
487*1c60b9acSAndroid Build Coastguard Worker 	if (pollfd->revents & LWS_POLLOUT)
488*1c60b9acSAndroid Build Coastguard Worker 		flags |= DBUS_WATCH_WRITABLE;
489*1c60b9acSAndroid Build Coastguard Worker 
490*1c60b9acSAndroid Build Coastguard Worker 	if (pollfd->revents & (LWS_POLLHUP))
491*1c60b9acSAndroid Build Coastguard Worker 		ctx->hup = 1;
492*1c60b9acSAndroid Build Coastguard Worker 
493*1c60b9acSAndroid Build Coastguard Worker 	/*
494*1c60b9acSAndroid Build Coastguard Worker 	 * POLLIN + POLLOUT gets us called here on the corresponding shadow
495*1c60b9acSAndroid Build Coastguard Worker 	 * wsi.  wsi->opaque_parent_data is the watcher handle bound to the wsi
496*1c60b9acSAndroid Build Coastguard Worker 	 */
497*1c60b9acSAndroid Build Coastguard Worker 
498*1c60b9acSAndroid Build Coastguard Worker 	for (n = 0; n < (int)LWS_ARRAY_SIZE(ctx->w); n++)
499*1c60b9acSAndroid Build Coastguard Worker 		if (ctx->w[n] && !dbus_watch_handle(ctx->w[n], flags))
500*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: dbus_watch_handle failed\n", __func__);
501*1c60b9acSAndroid Build Coastguard Worker 
502*1c60b9acSAndroid Build Coastguard Worker 	if (ctx->conn) {
503*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: conn: flags %d\n", __func__, flags);
504*1c60b9acSAndroid Build Coastguard Worker 
505*1c60b9acSAndroid Build Coastguard Worker 		while (dbus_connection_get_dispatch_status(ctx->conn) ==
506*1c60b9acSAndroid Build Coastguard Worker 						DBUS_DISPATCH_DATA_REMAINS)
507*1c60b9acSAndroid Build Coastguard Worker 			dbus_connection_dispatch(ctx->conn);
508*1c60b9acSAndroid Build Coastguard Worker 
509*1c60b9acSAndroid Build Coastguard Worker 		handle_dispatch_status(NULL, DBUS_DISPATCH_DATA_REMAINS, NULL);
510*1c60b9acSAndroid Build Coastguard Worker 
511*1c60b9acSAndroid Build Coastguard Worker 		__check_destroy_shadow_wsi(ctx, wsi);
512*1c60b9acSAndroid Build Coastguard Worker 	} else
513*1c60b9acSAndroid Build Coastguard Worker 		if (ctx->dbs)
514*1c60b9acSAndroid Build Coastguard Worker 			/* ??? */
515*1c60b9acSAndroid Build Coastguard Worker 			lwsl_debug("%s: dbs: %d\n", __func__, flags);
516*1c60b9acSAndroid Build Coastguard Worker 
517*1c60b9acSAndroid Build Coastguard Worker 	return LWS_HPI_RET_HANDLED;
518*1c60b9acSAndroid Build Coastguard Worker }
519*1c60b9acSAndroid Build Coastguard Worker 
520*1c60b9acSAndroid Build Coastguard Worker static int
rops_pt_init_destroy_dbus(struct lws_context * context,const struct lws_context_creation_info * info,struct lws_context_per_thread * pt,int destroy)521*1c60b9acSAndroid Build Coastguard Worker rops_pt_init_destroy_dbus(struct lws_context *context,
522*1c60b9acSAndroid Build Coastguard Worker 		    const struct lws_context_creation_info *info,
523*1c60b9acSAndroid Build Coastguard Worker 		    struct lws_context_per_thread *pt, int destroy)
524*1c60b9acSAndroid Build Coastguard Worker {
525*1c60b9acSAndroid Build Coastguard Worker 	if (destroy)
526*1c60b9acSAndroid Build Coastguard Worker 		lws_sul_cancel(&pt->dbus.sul);
527*1c60b9acSAndroid Build Coastguard Worker 
528*1c60b9acSAndroid Build Coastguard Worker 	return 0;
529*1c60b9acSAndroid Build Coastguard Worker }
530*1c60b9acSAndroid Build Coastguard Worker 
531*1c60b9acSAndroid Build Coastguard Worker static const lws_rops_t rops_table_dbus[] = {
532*1c60b9acSAndroid Build Coastguard Worker 	/*  1 */ { .pt_init_destroy	= rops_pt_init_destroy_dbus },
533*1c60b9acSAndroid Build Coastguard Worker 	/*  2 */ { .handle_POLLIN	= rops_handle_POLLIN_dbus },
534*1c60b9acSAndroid Build Coastguard Worker };
535*1c60b9acSAndroid Build Coastguard Worker 
536*1c60b9acSAndroid Build Coastguard Worker const struct lws_role_ops role_ops_dbus = {
537*1c60b9acSAndroid Build Coastguard Worker 	/* role name */			"dbus",
538*1c60b9acSAndroid Build Coastguard Worker 	/* alpn id */			NULL,
539*1c60b9acSAndroid Build Coastguard Worker 
540*1c60b9acSAndroid Build Coastguard Worker 	/* rops_table */		rops_table_dbus,
541*1c60b9acSAndroid Build Coastguard Worker 	/* rops_idx */			{
542*1c60b9acSAndroid Build Coastguard Worker 	  /* LWS_ROPS_check_upgrades */
543*1c60b9acSAndroid Build Coastguard Worker 	  /* LWS_ROPS_pt_init_destroy */		0x01,
544*1c60b9acSAndroid Build Coastguard Worker 	  /* LWS_ROPS_init_vhost */
545*1c60b9acSAndroid Build Coastguard Worker 	  /* LWS_ROPS_destroy_vhost */			0x00,
546*1c60b9acSAndroid Build Coastguard Worker 	  /* LWS_ROPS_service_flag_pending */
547*1c60b9acSAndroid Build Coastguard Worker 	  /* LWS_ROPS_handle_POLLIN */			0x02,
548*1c60b9acSAndroid Build Coastguard Worker 	  /* LWS_ROPS_handle_POLLOUT */
549*1c60b9acSAndroid Build Coastguard Worker 	  /* LWS_ROPS_perform_user_POLLOUT */		0x00,
550*1c60b9acSAndroid Build Coastguard Worker 	  /* LWS_ROPS_callback_on_writable */
551*1c60b9acSAndroid Build Coastguard Worker 	  /* LWS_ROPS_tx_credit */			0x00,
552*1c60b9acSAndroid Build Coastguard Worker 	  /* LWS_ROPS_write_role_protocol */
553*1c60b9acSAndroid Build Coastguard Worker 	  /* LWS_ROPS_encapsulation_parent */		0x00,
554*1c60b9acSAndroid Build Coastguard Worker 	  /* LWS_ROPS_alpn_negotiated */
555*1c60b9acSAndroid Build Coastguard Worker 	  /* LWS_ROPS_close_via_role_protocol */	0x00,
556*1c60b9acSAndroid Build Coastguard Worker 	  /* LWS_ROPS_close_role */
557*1c60b9acSAndroid Build Coastguard Worker 	  /* LWS_ROPS_close_kill_connection */		0x00,
558*1c60b9acSAndroid Build Coastguard Worker 	  /* LWS_ROPS_destroy_role */
559*1c60b9acSAndroid Build Coastguard Worker 	  /* LWS_ROPS_adoption_bind */			0x00,
560*1c60b9acSAndroid Build Coastguard Worker 	  /* LWS_ROPS_client_bind */
561*1c60b9acSAndroid Build Coastguard Worker 	  /* LWS_ROPS_issue_keepalive */		0x00,
562*1c60b9acSAndroid Build Coastguard Worker 					},
563*1c60b9acSAndroid Build Coastguard Worker 
564*1c60b9acSAndroid Build Coastguard Worker 	/* adoption_cb clnt, srv */	{ 0, 0 },
565*1c60b9acSAndroid Build Coastguard Worker 	/* rx_cb clnt, srv */		{ 0, 0 },
566*1c60b9acSAndroid Build Coastguard Worker 	/* writeable cb clnt, srv */	{ 0, 0 },
567*1c60b9acSAndroid Build Coastguard Worker 	/* close cb clnt, srv */	{ 0, 0 },
568*1c60b9acSAndroid Build Coastguard Worker 	/* protocol_bind_cb c,s */	{ 0, 0 },
569*1c60b9acSAndroid Build Coastguard Worker 	/* protocol_unbind_cb c,s */	{ 0, 0 },
570*1c60b9acSAndroid Build Coastguard Worker 	/* file_handle */		0,
571*1c60b9acSAndroid Build Coastguard Worker };
572