README.md
1## Information for new event lib implementers
2
3### Introduction
4
5By default lws has built-in support for POSIX poll() as the event loop.
6
7However either to get access to epoll() or other platform specific better
8poll waits, or to integrate with existing applications already using a
9specific event loop, it can be desirable for lws to use another external
10event library, like libuv, libevent or libev.
11
12### Code placement
13
14The code specific to the event library should live in `./lib/event-libs/**lib name**`
15
16### Allowing control over enabling event libs
17
18All event libs should add a cmake define `LWS_WITH_**lib name**` and make its build
19dependent on it in CMakeLists.txt. Export the cmakedefine in `./cmake/lws_config.h.in`
20as well so user builds can understand if the event lib is available in the lws build it is
21trying to bind to.
22
23If the event lib is disabled in cmake, nothing in its directory is built or referenced.
24
25### Event loop ops struct
26
27The event lib support is defined by `struct lws_event_loop_ops` in `lib/event-libs/private-lib-event-libs.h`,
28each event lib support instantiates one of these and fills in the appropriate ops
29callbacks to perform its job. By convention that lives in
30`./lib/event-libs/**lib name**/**lib_name**.c`.
31
32### Private event lib declarations
33
34Truly private declarations for the event lib can go in the event-libs directory as you like.
35However when the declarations must be accessible to other things in lws build, eg,
36the event lib support adds members to `struct lws` when enabled, they should be in the
37event lib support directory in a file `private-lib-event-libs-myeventlib.h`.
38
39Search for "bring in event libs private declarations" in `./lib/core/private-lib-core.h
40and add your private event lib support file there following the style used for the other
41event libs, eg,
42
43```
44#if defined(LWS_WITH_LIBUV)
45 #include "event-libs/libuv/private-lib-event-libs-libuv.h"
46#endif
47```
48
49If the event lib support is disabled at cmake, nothing from its private.h should be used anywhere.
50
51### Integrating event lib assets to lws
52
53If your event lib needs special storage in lws objects, that's no problem. But to keep
54things sane, there are some rules.
55
56 - declare a "container struct" in your private.h for everything, eg, the libuv event
57 lib support need to add its own assets in the perthread struct, it declares in its private.h
58
59```
60struct lws_pt_eventlibs_libuv {
61 uv_loop_t *io_loop;
62 uv_signal_t signals[8];
63 uv_timer_t timeout_watcher;
64 uv_timer_t hrtimer;
65 uv_idle_t idle;
66};
67```
68
69 - add your event lib content in one place in the related lws struct, protected by `#if defined(LWS_WITH_**lib name**)`,
70 eg, again for LWS_WITH_LIBUV
71
72```
73struct lws_context_per_thread {
74
75...
76
77#if defined(LWS_WITH_LIBUV)
78 struct lws_pt_eventlibs_libuv uv;
79#endif
80
81...
82```
83
84### Adding to lws available event libs list
85
86Edit the NULL-terminated array `available_event_libs` at the top of `./lib/context.c` to include
87a pointer to your new event lib support's ops struct, following the style already there.
88
89```
90const struct lws_event_loop_ops *available_event_libs[] = {
91#if defined(LWS_WITH_POLL)
92 &event_loop_ops_poll,
93#endif
94#if defined(LWS_WITH_LIBUV)
95 &event_loop_ops_uv,
96#endif
97...
98```
99
100This is used to provide a list of avilable configured backends.
101
102### Enabling event lib adoption
103
104You need to add a `LWS_SERVER_OPTION...` flag as necessary in `./lib/libwebsockets.h`
105`enum lws_context_options`, and follow the existing code in `lws_create_context()`
106to convert the flag into binding your ops struct to the context.
107
108### Implementation of the event lib bindings
109
110Study eg libuv implementation, using the available ops in the struct lws_event_loop_ops
111as a guide.
112
113### Destruction
114
115Ending the event loop is generally a bit tricky, because if the event loop is internal
116to the lws context, you cannot destroy it while the event loop is running.
117
118Don't add special exports... we tried that, it's a huge mess. The same user code should be able
119work with any of the event loops including poll.
120
121The solution we found was hide the different processing necessary for the different cases in
122lws_destroy_context(). To help with that there are ops available at two different places in
123the context destroy processing.
124
125