xref: /aosp_15_r20/external/libwebsockets/lib/event-libs/README.md (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker## Information for new event lib implementers
2*1c60b9acSAndroid Build Coastguard Worker
3*1c60b9acSAndroid Build Coastguard Worker### Introduction
4*1c60b9acSAndroid Build Coastguard Worker
5*1c60b9acSAndroid Build Coastguard WorkerBy default lws has built-in support for POSIX poll() as the event loop on unix,
6*1c60b9acSAndroid Build Coastguard Workerand native WSA on windows.
7*1c60b9acSAndroid Build Coastguard Worker
8*1c60b9acSAndroid Build Coastguard WorkerTo get access to epoll() or other platform specific better poll waits, or to
9*1c60b9acSAndroid Build Coastguard Workerintegrate with existing applications already using a specific event loop, it can
10*1c60b9acSAndroid Build Coastguard Workerbe desirable for lws to use another external event library, like libuv, glib,
11*1c60b9acSAndroid Build Coastguard Workerlibevent, libev, or sdevent.
12*1c60b9acSAndroid Build Coastguard Worker
13*1c60b9acSAndroid Build Coastguard WorkerLws supports wholesale replacement of its wait selectable at runtime, either by
14*1c60b9acSAndroid Build Coastguard Workerbuilding support for one or more event lib into the libwebsockets library, or by
15*1c60b9acSAndroid Build Coastguard Workerbuilding runtime-loadable plugins.  CMake symbol `LWS_WITH_EVLIB_PLUGINS`
16*1c60b9acSAndroid Build Coastguard Workerdecides if the support is built as plugins or included into the lws lib.
17*1c60b9acSAndroid Build Coastguard Worker
18*1c60b9acSAndroid Build Coastguard WorkerDue to their history libevent and libev have conflicting defines in the same
19*1c60b9acSAndroid Build Coastguard Workernamespace and cannot be built together if included into the lib, however when
20*1c60b9acSAndroid Build Coastguard Workerbuilt as plugins they are built separately without problems.
21*1c60b9acSAndroid Build Coastguard WorkerSee ./READMEs/README.event-libs.md for more details.
22*1c60b9acSAndroid Build Coastguard Worker
23*1c60b9acSAndroid Build Coastguard WorkerDespite it may be more work, lws event lib implementations must support
24*1c60b9acSAndroid Build Coastguard Worker"foreign" loops cleanly, that is integration with an already-existing loop and
25*1c60b9acSAndroid Build Coastguard Workerthe ability to destroy the lws_context without stopping or leaving the foreign
26*1c60b9acSAndroid Build Coastguard Workerloop in any different state than when lws found it.  For most loops this is
27*1c60b9acSAndroid Build Coastguard Workerfairly simple, but with libuv async close, it required refcounting lws libuv
28*1c60b9acSAndroid Build Coastguard Workerhandles and deferring the actual destroy until they were all really closed.
29*1c60b9acSAndroid Build Coastguard Worker
30*1c60b9acSAndroid Build Coastguard Worker### Code placement
31*1c60b9acSAndroid Build Coastguard Worker
32*1c60b9acSAndroid Build Coastguard WorkerThe code specific to the event library should live in `./lib/event-libs/**lib name**`
33*1c60b9acSAndroid Build Coastguard Worker
34*1c60b9acSAndroid Build Coastguard Worker### Allowing control over enabling event libs
35*1c60b9acSAndroid Build Coastguard Worker
36*1c60b9acSAndroid Build Coastguard WorkerAll event libs should add a cmake define `LWS_WITH_**lib name**` and make its
37*1c60b9acSAndroid Build Coastguard Workerbuild dependent on it in CMakeLists.txt.  Export the cmakedefine in
38*1c60b9acSAndroid Build Coastguard Worker`./cmake/lws_config.h.in` as well so user builds can understand if the event
39*1c60b9acSAndroid Build Coastguard Workerlib is available in the lws build it is trying to bind to.
40*1c60b9acSAndroid Build Coastguard Worker
41*1c60b9acSAndroid Build Coastguard WorkerIf the event lib is disabled in cmake, nothing in its directory is built or
42*1c60b9acSAndroid Build Coastguard Workerreferenced.
43*1c60b9acSAndroid Build Coastguard Worker
44*1c60b9acSAndroid Build Coastguard Worker### Event loop ops struct
45*1c60b9acSAndroid Build Coastguard Worker
46*1c60b9acSAndroid Build Coastguard WorkerThe event lib support is defined by `struct lws_event_loop_ops` in
47*1c60b9acSAndroid Build Coastguard Worker`lib/event-libs/private-lib-event-libs.h`,
48*1c60b9acSAndroid Build Coastguard Workereach event lib support instantiates one of these and fills in the appropriate
49*1c60b9acSAndroid Build Coastguard Workerops callbacks to perform its job.  By convention that lives in
50*1c60b9acSAndroid Build Coastguard Worker`./lib/event-libs/**lib name**/**lib_name**.c`.
51*1c60b9acSAndroid Build Coastguard Worker
52*1c60b9acSAndroid Build Coastguard WorkerThe ops struct must be public, not static, and must be named using `**lib_name**`,
53*1c60b9acSAndroid Build Coastguard Workereg
54*1c60b9acSAndroid Build Coastguard Worker
55*1c60b9acSAndroid Build Coastguard Worker```
56*1c60b9acSAndroid Build Coastguard Worker```
57*1c60b9acSAndroid Build Coastguard Worker
58*1c60b9acSAndroid Build Coastguard Worker### Private event lib declarations
59*1c60b9acSAndroid Build Coastguard Worker
60*1c60b9acSAndroid Build Coastguard WorkerTruly private declarations for the event lib support that are only referenced by
61*1c60b9acSAndroid Build Coastguard Workerthat code can go in the event-libs directory as you like.  The convention is
62*1c60b9acSAndroid Build Coastguard Workerthey should be in the event lib support directory in a file
63*1c60b9acSAndroid Build Coastguard Worker`private-lib-event-libs-**lib name**.h`.
64*1c60b9acSAndroid Build Coastguard Worker
65*1c60b9acSAndroid Build Coastguard Worker### Integration with lws
66*1c60b9acSAndroid Build Coastguard Worker
67*1c60b9acSAndroid Build Coastguard WorkerThere are a couple of places to add refererences in ./lib/core/context.c, in a
68*1c60b9acSAndroid Build Coastguard Workertable of context creation time server option flags mapped to the **lib_name**,
69*1c60b9acSAndroid Build Coastguard Workerused for plugin mode, like this...
70*1c60b9acSAndroid Build Coastguard Worker
71*1c60b9acSAndroid Build Coastguard Worker```
72*1c60b9acSAndroid Build Coastguard Worker#if defined(LWS_WITH_EVLIB_PLUGINS) && defined(LWS_WITH_EVENT_LIBS)
73*1c60b9acSAndroid Build Coastguard Workerstatic const struct lws_evlib_map {
74*1c60b9acSAndroid Build Coastguard Worker	uint64_t	flag;
75*1c60b9acSAndroid Build Coastguard Worker	const char	*name;
76*1c60b9acSAndroid Build Coastguard Worker} map[] = {
77*1c60b9acSAndroid Build Coastguard Worker	{ LWS_SERVER_OPTION_LIBUV,    "evlib_uv" },
78*1c60b9acSAndroid Build Coastguard Worker	{ LWS_SERVER_OPTION_LIBEVENT, "evlib_event" },
79*1c60b9acSAndroid Build Coastguard Worker	{ LWS_SERVER_OPTION_GLIB,     "evlib_glib" },
80*1c60b9acSAndroid Build Coastguard Worker	{ LWS_SERVER_OPTION_LIBEV,    "evlib_ev" },
81*1c60b9acSAndroid Build Coastguard Worker};
82*1c60b9acSAndroid Build Coastguard Worker```
83*1c60b9acSAndroid Build Coastguard Worker
84*1c60b9acSAndroid Build Coastguard Workerand for backwards compatibility add a stanza to the built-in checks like this
85*1c60b9acSAndroid Build Coastguard Worker
86*1c60b9acSAndroid Build Coastguard Worker```
87*1c60b9acSAndroid Build Coastguard Worker#if defined(LWS_WITH_LIBUV)
88*1c60b9acSAndroid Build Coastguard Worker	if (lws_check_opt(info->options, LWS_SERVER_OPTION_LIBUV)) {
89*1c60b9acSAndroid Build Coastguard Worker		extern const lws_plugin_evlib_t evlib_uv;
90*1c60b9acSAndroid Build Coastguard Worker		plev = &evlib_uv;
91*1c60b9acSAndroid Build Coastguard Worker	}
92*1c60b9acSAndroid Build Coastguard Worker#endif
93*1c60b9acSAndroid Build Coastguard Worker```
94*1c60b9acSAndroid Build Coastguard Worker
95*1c60b9acSAndroid Build Coastguard WorkerBoth entries are the way the main libs hook up to the selected event lib ops
96*1c60b9acSAndroid Build Coastguard Workerstruct at runtime.
97*1c60b9acSAndroid Build Coastguard Worker
98*1c60b9acSAndroid Build Coastguard Worker### Integrating event lib assets to lws
99*1c60b9acSAndroid Build Coastguard Worker
100*1c60b9acSAndroid Build Coastguard WorkerDeclare "container structs" in your private....h for anything you need at
101*1c60b9acSAndroid Build Coastguard Workerwsi, pt, vhost and context levels, eg, the libuv event lib support need to
102*1c60b9acSAndroid Build Coastguard Workeradd its own assets in the perthread struct, it declares in its private....h
103*1c60b9acSAndroid Build Coastguard Worker
104*1c60b9acSAndroid Build Coastguard Worker```
105*1c60b9acSAndroid Build Coastguard Workerstruct lws_pt_eventlibs_libuv {
106*1c60b9acSAndroid Build Coastguard Worker	uv_loop_t *io_loop;
107*1c60b9acSAndroid Build Coastguard Worker	struct lws_context_per_thread *pt;
108*1c60b9acSAndroid Build Coastguard Worker	uv_signal_t signals[8];
109*1c60b9acSAndroid Build Coastguard Worker	uv_timer_t sultimer;
110*1c60b9acSAndroid Build Coastguard Worker	uv_idle_t idle;
111*1c60b9acSAndroid Build Coastguard Worker	struct lws_signal_watcher_libuv w_sigint;
112*1c60b9acSAndroid Build Coastguard Worker};
113*1c60b9acSAndroid Build Coastguard Worker```
114*1c60b9acSAndroid Build Coastguard Worker
115*1c60b9acSAndroid Build Coastguard Workerthis is completely private and opaque, but in the ops struct there are provided
116*1c60b9acSAndroid Build Coastguard Workerfour entries to export the sizes of these event-lib specific objects
117*1c60b9acSAndroid Build Coastguard Worker
118*1c60b9acSAndroid Build Coastguard Worker```
119*1c60b9acSAndroid Build Coastguard Worker...
120*1c60b9acSAndroid Build Coastguard Worker	/* evlib_size_ctx */	sizeof(struct lws_context_eventlibs_libuv),
121*1c60b9acSAndroid Build Coastguard Worker	/* evlib_size_pt */	sizeof(struct lws_pt_eventlibs_libuv),
122*1c60b9acSAndroid Build Coastguard Worker	/* evlib_size_vh */	0,
123*1c60b9acSAndroid Build Coastguard Worker	/* evlib_size_wsi */	sizeof(struct lws_io_watcher_libuv),
124*1c60b9acSAndroid Build Coastguard Worker};
125*1c60b9acSAndroid Build Coastguard Worker```
126*1c60b9acSAndroid Build Coastguard Worker
127*1c60b9acSAndroid Build Coastguard WorkerIf the particular event lib doesn't need to have a private footprint in an
128*1c60b9acSAndroid Build Coastguard Workerobject, it can just set the size it needs there to 0.
129*1c60b9acSAndroid Build Coastguard Worker
130*1c60b9acSAndroid Build Coastguard WorkerWhen the context, pts, vhosts or wsis are created in lws, they over-allocate
131*1c60b9acSAndroid Build Coastguard Workerto also allow for the event lib object, and set a pointer in the lws object
132*1c60b9acSAndroid Build Coastguard Workerbeing created to point at the over-allocation.  For example for the wsi
133*1c60b9acSAndroid Build Coastguard Worker
134*1c60b9acSAndroid Build Coastguard Worker```
135*1c60b9acSAndroid Build Coastguard Worker#if defined(LWS_WITH_EVENT_LIBS)
136*1c60b9acSAndroid Build Coastguard Worker	void				*evlib_wsi; /* overallocated */
137*1c60b9acSAndroid Build Coastguard Worker#endif
138*1c60b9acSAndroid Build Coastguard Worker```
139*1c60b9acSAndroid Build Coastguard Worker
140*1c60b9acSAndroid Build Coastguard Workerand similarly there are `evlib_pt` and so on for those objects, usable by the
141*1c60b9acSAndroid Build Coastguard Workerevent lib and opaque to everyone else.  Once the event lib is selected at
142*1c60b9acSAndroid Build Coastguard Workerruntime, all of these objects are guaranteed to have the right size object at
143*1c60b9acSAndroid Build Coastguard Worker`wsi->evlib_wsi` initialized to zeroes.
144*1c60b9acSAndroid Build Coastguard Worker
145*1c60b9acSAndroid Build Coastguard Worker### Enabling event lib adoption
146*1c60b9acSAndroid Build Coastguard Worker
147*1c60b9acSAndroid Build Coastguard WorkerYou need to add a `LWS_SERVER_OPTION...` flag as necessary in `./lib/libwebsockets.h`
148*1c60b9acSAndroid Build Coastguard Worker`enum lws_context_options`, and follow the existing code in `lws_create_context()`
149*1c60b9acSAndroid Build Coastguard Workerto convert the flag into binding your ops struct to the context.
150*1c60b9acSAndroid Build Coastguard Worker
151*1c60b9acSAndroid Build Coastguard Worker### Implementation of the event lib bindings
152*1c60b9acSAndroid Build Coastguard Worker
153*1c60b9acSAndroid Build Coastguard WorkerStudy eg libuv implementation, using the available ops in the struct lws_event_loop_ops
154*1c60b9acSAndroid Build Coastguard Workeras a guide.
155*1c60b9acSAndroid Build Coastguard Worker
156*1c60b9acSAndroid Build Coastguard Worker### Destruction
157*1c60b9acSAndroid Build Coastguard Worker
158*1c60b9acSAndroid Build Coastguard WorkerEnding the event loop is generally a bit tricky, because if the event loop is
159*1c60b9acSAndroid Build Coastguard Workerinternal to the lws context, you cannot destroy it while the event loop is
160*1c60b9acSAndroid Build Coastguard Workerrunning.
161*1c60b9acSAndroid Build Coastguard Worker
162*1c60b9acSAndroid Build Coastguard WorkerDon't add special exports... we tried that, it's a huge mess.  The same user
163*1c60b9acSAndroid Build Coastguard Workercode should be able work with any of the event loops including poll.
164*1c60b9acSAndroid Build Coastguard Worker
165*1c60b9acSAndroid Build Coastguard WorkerThe solution we found was hide the different processing necessary for the
166*1c60b9acSAndroid Build Coastguard Workerdifferent cases in `lws_destroy_context()`.  To help with that there are event
167*1c60b9acSAndroid Build Coastguard Workerlib ops available that will be called at two different places in the context
168*1c60b9acSAndroid Build Coastguard Workerdestroy processing.
169*1c60b9acSAndroid Build Coastguard Worker
170