xref: /aosp_15_r20/external/libwebsockets/READMEs/README.event-loops-intro.md (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker# Considerations around Event Loops
2*1c60b9acSAndroid Build Coastguard Worker
3*1c60b9acSAndroid Build Coastguard WorkerMuch of the software we use is written around an **event loop**.  Some examples
4*1c60b9acSAndroid Build Coastguard Worker
5*1c60b9acSAndroid Build Coastguard Worker - Chrome / Chromium, transmission, tmux, ntp SNTP... [libevent](https://libevent.org/)
6*1c60b9acSAndroid Build Coastguard Worker - node.js / cjdns / Julia / cmake ... [libuv](https://archive.is/64pOt)
7*1c60b9acSAndroid Build Coastguard Worker - Gstreamer, Gnome / GTK apps ... [glib](https://people.gnome.org/~desrt/glib-docs/glib-The-Main-Event-Loop.html)
8*1c60b9acSAndroid Build Coastguard Worker - SystemD ... sdevent
9*1c60b9acSAndroid Build Coastguard Worker - OpenWRT ... uloop
10*1c60b9acSAndroid Build Coastguard Worker
11*1c60b9acSAndroid Build Coastguard WorkerMany applications roll their own event loop using poll() or epoll() or similar,
12*1c60b9acSAndroid Build Coastguard Workerusing the same techniques.  Another set of apps use message dispatchers that
13*1c60b9acSAndroid Build Coastguard Workertake the same approach, but are for cases that don't need to support sockets.
14*1c60b9acSAndroid Build Coastguard WorkerEvent libraries provide crossplatform abstractions for this functoinality, and
15*1c60b9acSAndroid Build Coastguard Workerprovide the best backend for their event waits on the platform automagically.
16*1c60b9acSAndroid Build Coastguard Worker
17*1c60b9acSAndroid Build Coastguard Workerlibwebsockets networking operations require an event loop, it provides a default
18*1c60b9acSAndroid Build Coastguard Workerone for the platform (based on poll() for Unix) if needed, but also can natively
19*1c60b9acSAndroid Build Coastguard Workeruse any of the event loop libraries listed above, including "foreign" loops
20*1c60b9acSAndroid Build Coastguard Workeralready created and managed by the application.
21*1c60b9acSAndroid Build Coastguard Worker
22*1c60b9acSAndroid Build Coastguard Worker## What is an 'event loop'?
23*1c60b9acSAndroid Build Coastguard Worker
24*1c60b9acSAndroid Build Coastguard WorkerEvent loops have the following characteristics:
25*1c60b9acSAndroid Build Coastguard Worker
26*1c60b9acSAndroid Build Coastguard Worker - they have a **single thread**, therefore they do not require locking
27*1c60b9acSAndroid Build Coastguard Worker - they are **not threadsafe**
28*1c60b9acSAndroid Build Coastguard Worker - they require **nonblocking IO**
29*1c60b9acSAndroid Build Coastguard Worker - they **sleep** while there are no events (aka the "event wait")
30*1c60b9acSAndroid Build Coastguard Worker - if one or more event seen, they call back into user code to handle each in
31*1c60b9acSAndroid Build Coastguard Worker   turn and then return to the wait (ie, "loop")
32*1c60b9acSAndroid Build Coastguard Worker
33*1c60b9acSAndroid Build Coastguard Worker### They have a single thread
34*1c60b9acSAndroid Build Coastguard Worker
35*1c60b9acSAndroid Build Coastguard WorkerBy doing everything in turn on a single thread, there can be no possibility of
36*1c60b9acSAndroid Build Coastguard Workerconflicting access to resources from different threads... if the single thread
37*1c60b9acSAndroid Build Coastguard Workeris in callback A, it cannot be in two places at the same time and also in
38*1c60b9acSAndroid Build Coastguard Workercallback B accessing the same thing: it can never run any other code
39*1c60b9acSAndroid Build Coastguard Workerconcurrently, only sequentially, by design.
40*1c60b9acSAndroid Build Coastguard Worker
41*1c60b9acSAndroid Build Coastguard WorkerIt means that all mutexes and other synchronization and locking can be
42*1c60b9acSAndroid Build Coastguard Workereliminated, along with the many kinds of bugs related to them.
43*1c60b9acSAndroid Build Coastguard Worker
44*1c60b9acSAndroid Build Coastguard Worker### They are not threadsafe
45*1c60b9acSAndroid Build Coastguard Worker
46*1c60b9acSAndroid Build Coastguard WorkerEvent loops mandate doing everything in a single thread.  You cannot call their
47*1c60b9acSAndroid Build Coastguard Workerapis from other threads, since there is no protection against reentrancy.
48*1c60b9acSAndroid Build Coastguard Worker
49*1c60b9acSAndroid Build Coastguard WorkerLws apis cannot be called safely from any thread other than the event loop one,
50*1c60b9acSAndroid Build Coastguard Workerwith the sole exception of `lws_cancel_service()`.
51*1c60b9acSAndroid Build Coastguard Worker
52*1c60b9acSAndroid Build Coastguard Worker### They have nonblocking IO
53*1c60b9acSAndroid Build Coastguard Worker
54*1c60b9acSAndroid Build Coastguard WorkerWith blocking IO, you have to create threads in order to block them to learn
55*1c60b9acSAndroid Build Coastguard Workerwhen your IO could proceed.  In an event loop, all descriptors are set to use
56*1c60b9acSAndroid Build Coastguard Workernonblocking mode, we only attempt to read or write when we have been informed by
57*1c60b9acSAndroid Build Coastguard Workeran event that there is something to read, or it is possible to write.
58*1c60b9acSAndroid Build Coastguard Worker
59*1c60b9acSAndroid Build Coastguard WorkerSo sacrificial, blocking discrete IO threads are also eliminated, we just do
60*1c60b9acSAndroid Build Coastguard Workerwhat we should do sequentially, when we get the event indicating that we should
61*1c60b9acSAndroid Build Coastguard Workerdo it.
62*1c60b9acSAndroid Build Coastguard Worker
63*1c60b9acSAndroid Build Coastguard Worker### They sleep while there are no events
64*1c60b9acSAndroid Build Coastguard Worker
65*1c60b9acSAndroid Build Coastguard WorkerAn OS "wait" of some kind is used to sleep the event loop thread until something
66*1c60b9acSAndroid Build Coastguard Workerto do.  There's an explicit wait on file descriptors that have pending read or
67*1c60b9acSAndroid Build Coastguard Workerwrite, and also an implicit wait for the next scheduled event.  Even if idle for
68*1c60b9acSAndroid Build Coastguard Workerdescriptor events, the event loop will wake and handle scheduled events at the
69*1c60b9acSAndroid Build Coastguard Workerright time.
70*1c60b9acSAndroid Build Coastguard Worker
71*1c60b9acSAndroid Build Coastguard WorkerIn an idle system, the event loop stays in the wait and takes 0% CPU.
72*1c60b9acSAndroid Build Coastguard Worker
73*1c60b9acSAndroid Build Coastguard Worker### If one or more event, they handle them and then return to sleep
74*1c60b9acSAndroid Build Coastguard Worker
75*1c60b9acSAndroid Build Coastguard WorkerAs you can expect from "event loop", it is an infinite loop alternating between
76*1c60b9acSAndroid Build Coastguard Workersleeping in the event wait and sequentially servicing pending events, by calling
77*1c60b9acSAndroid Build Coastguard Workercallbacks for each event on each object.
78*1c60b9acSAndroid Build Coastguard Worker
79*1c60b9acSAndroid Build Coastguard WorkerThe callbacks handle the event and then "return to the event loop".  The state
80*1c60b9acSAndroid Build Coastguard Workerof things in the loop itself is guaranteed to stay consistent while in a user
81*1c60b9acSAndroid Build Coastguard Workercallback, until you return from the callback to the event loop, when socket
82*1c60b9acSAndroid Build Coastguard Workercloses may be processed and lead to object destruction.
83*1c60b9acSAndroid Build Coastguard Worker
84*1c60b9acSAndroid Build Coastguard WorkerEvent libraries like libevent are operating the same way, once you start the
85*1c60b9acSAndroid Build Coastguard Workerevent loop, it sits in an inifinite loop in the library, calling back on events
86*1c60b9acSAndroid Build Coastguard Workeruntil you "stop" or "break" the loop by calling apis.
87*1c60b9acSAndroid Build Coastguard Worker
88*1c60b9acSAndroid Build Coastguard Worker## Why are event libraries popular?
89*1c60b9acSAndroid Build Coastguard Worker
90*1c60b9acSAndroid Build Coastguard WorkerDevelopers prefer an external library solution for the event loop because:
91*1c60b9acSAndroid Build Coastguard Worker
92*1c60b9acSAndroid Build Coastguard Worker - the quality is generally higher than self-rolled ones.  Someone else is
93*1c60b9acSAndroid Build Coastguard Worker   maintaining it, a fulltime team in some cases.
94*1c60b9acSAndroid Build Coastguard Worker - the event libraries are crossplatform, they will pick the most effective
95*1c60b9acSAndroid Build Coastguard Worker   event wait for the platform without the developer having to know the details.
96*1c60b9acSAndroid Build Coastguard Worker   For example most libs can conceal whether the platform is windows or unix,
97*1c60b9acSAndroid Build Coastguard Worker   and use native waits like epoll() or WSA accordingly.
98*1c60b9acSAndroid Build Coastguard Worker - If your application uses a event library, it is possible to integrate very
99*1c60b9acSAndroid Build Coastguard Worker   cleanly with other libraries like lws that can use the same event library.
100*1c60b9acSAndroid Build Coastguard Worker   That is extremely messy or downright impossible to do with hand-rolled loops.
101*1c60b9acSAndroid Build Coastguard Worker
102*1c60b9acSAndroid Build Coastguard WorkerCompared to just throwing threads on it
103*1c60b9acSAndroid Build Coastguard Worker
104*1c60b9acSAndroid Build Coastguard Worker - thread lifecycle has to be closely managed, threads must start and must be
105*1c60b9acSAndroid Build Coastguard Worker   brought to an end in a controlled way.  Event loops may end and destroy
106*1c60b9acSAndroid Build Coastguard Worker   objects they control at any time a callback returns to the event loop.
107*1c60b9acSAndroid Build Coastguard Worker
108*1c60b9acSAndroid Build Coastguard Worker - threads may do things sequentially or genuinely concurrently, this requires
109*1c60b9acSAndroid Build Coastguard Worker   locking and careful management so only deterministic and expected things
110*1c60b9acSAndroid Build Coastguard Worker   happen at the user data.
111*1c60b9acSAndroid Build Coastguard Worker
112*1c60b9acSAndroid Build Coastguard Worker - threads do not scale well to, eg, serving tens of thousands of connections;
113*1c60b9acSAndroid Build Coastguard Worker   web servers use event loops.
114*1c60b9acSAndroid Build Coastguard Worker
115*1c60b9acSAndroid Build Coastguard Worker## Multiple codebases cooperating on one event loop
116*1c60b9acSAndroid Build Coastguard Worker
117*1c60b9acSAndroid Build Coastguard WorkerThe ideal situation is all your code operates via a single event loop thread.
118*1c60b9acSAndroid Build Coastguard WorkerFor lws-only code, including lws_protocols callbacks, this is the normal state
119*1c60b9acSAndroid Build Coastguard Workerof affairs.
120*1c60b9acSAndroid Build Coastguard Worker
121*1c60b9acSAndroid Build Coastguard WorkerWhen there is other code that also needs to handle events, say already existing
122*1c60b9acSAndroid Build Coastguard Workerapplication code, or code handling a protocol not supported by lws, there are a
123*1c60b9acSAndroid Build Coastguard Workerfew options to allow them to work together, which is "best" depends on the
124*1c60b9acSAndroid Build Coastguard Workerdetails of what you're trying to do and what the existing code looks like.
125*1c60b9acSAndroid Build Coastguard WorkerIn descending order of desirability:
126*1c60b9acSAndroid Build Coastguard Worker
127*1c60b9acSAndroid Build Coastguard Worker### 1) Use a common event library for both lws and application code
128*1c60b9acSAndroid Build Coastguard Worker
129*1c60b9acSAndroid Build Coastguard WorkerThis is the best choice for Linux-class devices.  If you write your application
130*1c60b9acSAndroid Build Coastguard Workerto use, eg, a libevent loop, then you only need to configure lws to also use
131*1c60b9acSAndroid Build Coastguard Workeryour libevent loop for them to be able to interoperate perfectly.  Lws will
132*1c60b9acSAndroid Build Coastguard Workeroperate as a guest on this "foreign loop", and can cleanly create and destroy
133*1c60b9acSAndroid Build Coastguard Workerits context on the loop without disturbing the loop.
134*1c60b9acSAndroid Build Coastguard Worker
135*1c60b9acSAndroid Build Coastguard WorkerIn addition, your application can merge and interoperate with any other
136*1c60b9acSAndroid Build Coastguard Workerlibevent-capable libraries the same way, and compared to hand-rolled loops, the
137*1c60b9acSAndroid Build Coastguard Workerquality will be higher.
138*1c60b9acSAndroid Build Coastguard Worker
139*1c60b9acSAndroid Build Coastguard Worker### 2) Use lws native wsi semantics in the other code too
140*1c60b9acSAndroid Build Coastguard Worker
141*1c60b9acSAndroid Build Coastguard WorkerLws supports raw sockets and file fd abstractions inside the event loop.  So if
142*1c60b9acSAndroid Build Coastguard Workeryour other code fits into that model, one way is to express your connections as
143*1c60b9acSAndroid Build Coastguard Worker"RAW" wsis and handle them using lws_protocols callback semantics.
144*1c60b9acSAndroid Build Coastguard Worker
145*1c60b9acSAndroid Build Coastguard WorkerThis ties the application code to lws, but it has the advantage that the
146*1c60b9acSAndroid Build Coastguard Workerresulting code is aware of the underlying event loop implementation and will
147*1c60b9acSAndroid Build Coastguard Workerwork no matter what it is.
148*1c60b9acSAndroid Build Coastguard Worker
149*1c60b9acSAndroid Build Coastguard Worker### 3) Make a custom lws event lib shim for your custom loop
150*1c60b9acSAndroid Build Coastguard Worker
151*1c60b9acSAndroid Build Coastguard WorkerLws provides an ops struct abstraction in order to integrate with event
152*1c60b9acSAndroid Build Coastguard Workerlibraries, you can find it in ./includes/libwebsockets/lws-eventlib-exports.h.
153*1c60b9acSAndroid Build Coastguard Worker
154*1c60b9acSAndroid Build Coastguard WorkerLws uses this interface to implement its own event library plugins, but you can
155*1c60b9acSAndroid Build Coastguard Workeralso use it to make your own customized event loop shim, in the case there is
156*1c60b9acSAndroid Build Coastguard Workertoo much written for your custom event loop to be practical to change it.
157*1c60b9acSAndroid Build Coastguard Worker
158*1c60b9acSAndroid Build Coastguard WorkerIn other words this is a way to write a customized event lib "plugin" and tell
159*1c60b9acSAndroid Build Coastguard Workerthe lws_context to use it at creation time.  See [minimal-http-server.c](https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/http-server/minimal-http-server-eventlib-custom/minimal-http-server.c)
160*1c60b9acSAndroid Build Coastguard Worker
161*1c60b9acSAndroid Build Coastguard Worker### 4) Cooperate at thread level
162*1c60b9acSAndroid Build Coastguard Worker
163*1c60b9acSAndroid Build Coastguard WorkerThis is less desirable because it gives up on unifying the code to run from a
164*1c60b9acSAndroid Build Coastguard Workersingle thread, it means the codebases cannot call each other's apis directly.
165*1c60b9acSAndroid Build Coastguard Worker
166*1c60b9acSAndroid Build Coastguard WorkerIn this scheme the existing threads do their own thing, lock a shared
167*1c60b9acSAndroid Build Coastguard Workerarea of memory and list what they want done from the lws thread context, before
168*1c60b9acSAndroid Build Coastguard Workercalling `lws_cancel_service()` to break the lws event wait.  Lws will then
169*1c60b9acSAndroid Build Coastguard Workerbroadcast a `LWS_CALLBACK_EVENT_WAIT_CANCELLED` protocol callback, the handler
170*1c60b9acSAndroid Build Coastguard Workerfor which can lock the shared area and perform the requested operations from the
171*1c60b9acSAndroid Build Coastguard Workerlws thread context.
172*1c60b9acSAndroid Build Coastguard Worker
173*1c60b9acSAndroid Build Coastguard Worker### 5) Glue the loops together to wait sequentially (don't do this)
174*1c60b9acSAndroid Build Coastguard Worker
175*1c60b9acSAndroid Build Coastguard WorkerIf you have two or more chunks of code with their own waits, it may be tempting
176*1c60b9acSAndroid Build Coastguard Workerto have them wait sequentially in an outer event loop.  (This is only possible
177*1c60b9acSAndroid Build Coastguard Workerwith the lws default loop and not the event library support, event libraries
178*1c60b9acSAndroid Build Coastguard Workerhave this loop inside their own `...run(loop)` apis.)
179*1c60b9acSAndroid Build Coastguard Worker
180*1c60b9acSAndroid Build Coastguard Worker```
181*1c60b9acSAndroid Build Coastguard Worker	while (1) {
182*1c60b9acSAndroid Build Coastguard Worker		do_lws_wait(); /* interrupted at short intervals */
183*1c60b9acSAndroid Build Coastguard Worker		do_app_wait(); /* interrupted at short intervals */
184*1c60b9acSAndroid Build Coastguard Worker	}
185*1c60b9acSAndroid Build Coastguard Worker```
186*1c60b9acSAndroid Build Coastguard Worker
187*1c60b9acSAndroid Build Coastguard WorkerThis never works well, either:
188*1c60b9acSAndroid Build Coastguard Worker
189*1c60b9acSAndroid Build Coastguard Worker - the whole thing spins at 100% CPU when idle, or
190*1c60b9acSAndroid Build Coastguard Worker
191*1c60b9acSAndroid Build Coastguard Worker - the waits have timeouts where they sleep for short periods, but then the
192*1c60b9acSAndroid Build Coastguard Worker   latency to service on set of events is increased by the idle timeout period
193*1c60b9acSAndroid Build Coastguard Worker   of the wait for other set of events
194*1c60b9acSAndroid Build Coastguard Worker
195*1c60b9acSAndroid Build Coastguard Worker## Common Misunderstandings
196*1c60b9acSAndroid Build Coastguard Worker
197*1c60b9acSAndroid Build Coastguard Worker### "Real Men Use Threads"
198*1c60b9acSAndroid Build Coastguard Worker
199*1c60b9acSAndroid Build Coastguard WorkerSometimes you need threads or child processes.  But typically, whatever you're
200*1c60b9acSAndroid Build Coastguard Workertrying to do does not literally require threads.  Threads are an architectural
201*1c60b9acSAndroid Build Coastguard Workerchoice that can go either way depending on the goal and the constraints.
202*1c60b9acSAndroid Build Coastguard Worker
203*1c60b9acSAndroid Build Coastguard WorkerAny thread you add should have a clear reason to specifically be a thread and
204*1c60b9acSAndroid Build Coastguard Workernot done on the event loop, without a new thread or the consequent locking (and
205*1c60b9acSAndroid Build Coastguard Workerbugs).
206*1c60b9acSAndroid Build Coastguard Worker
207*1c60b9acSAndroid Build Coastguard Worker### But blocking IO is faster and simpler
208*1c60b9acSAndroid Build Coastguard Worker
209*1c60b9acSAndroid Build Coastguard WorkerNo, blocking IO has a lot of costs to conceal the event wait by blocking.
210*1c60b9acSAndroid Build Coastguard Worker
211*1c60b9acSAndroid Build Coastguard WorkerFor any IO that may wait, you must spawn an IO thread for it, purely to handle
212*1c60b9acSAndroid Build Coastguard Workerthe situation you get blocked in read() or write() for an arbitrary amount of
213*1c60b9acSAndroid Build Coastguard Workertime.  It buys you a simple story in one place, that you will proceed on the
214*1c60b9acSAndroid Build Coastguard Workerthread if read() or write() has completed, but costs threads and locking to get
215*1c60b9acSAndroid Build Coastguard Workerto that.
216*1c60b9acSAndroid Build Coastguard Worker
217*1c60b9acSAndroid Build Coastguard WorkerEvent loops dispense with the threads and locking, and still provide a simple
218*1c60b9acSAndroid Build Coastguard Workerstory, you will get called back when data arrives or you may send.
219*1c60b9acSAndroid Build Coastguard Worker
220*1c60b9acSAndroid Build Coastguard WorkerEvent loops can scale much better, a busy server with 50,000 connections active
221*1c60b9acSAndroid Build Coastguard Workerdoes not have to pay the overhead of 50,000 threads and their competing for
222*1c60b9acSAndroid Build Coastguard Workerlocking.
223*1c60b9acSAndroid Build Coastguard Worker
224*1c60b9acSAndroid Build Coastguard WorkerWith blocked threads, the thread can do no useful work at all while it is stuck
225*1c60b9acSAndroid Build Coastguard Workerwaiting.  With event loops the thread can service other events until something
226*1c60b9acSAndroid Build Coastguard Workerhappens on the fd.
227*1c60b9acSAndroid Build Coastguard Worker
228*1c60b9acSAndroid Build Coastguard Worker### Threads are inexpensive
229*1c60b9acSAndroid Build Coastguard Worker
230*1c60b9acSAndroid Build Coastguard WorkerIn the cases you really need threads, you must have them, or fork off another
231*1c60b9acSAndroid Build Coastguard Workerprocess.  But if you don't really need them, they bring with them a lot of
232*1c60b9acSAndroid Build Coastguard Workerexpense, some you may only notice when your code runs on constrained targets
233*1c60b9acSAndroid Build Coastguard Worker
234*1c60b9acSAndroid Build Coastguard Worker - threads have an OS-side footprint both as objects and in the scheduler
235*1c60b9acSAndroid Build Coastguard Worker
236*1c60b9acSAndroid Build Coastguard Worker - thread context switches are not slow on modern CPUs, but have side effects
237*1c60b9acSAndroid Build Coastguard Worker   like cache flushing
238*1c60b9acSAndroid Build Coastguard Worker
239*1c60b9acSAndroid Build Coastguard Worker - threads are designed to be blocked for arbitrary amounts of time if you use
240*1c60b9acSAndroid Build Coastguard Worker   blocking IO apis like write() or read().  Then how much concurrency is really
241*1c60b9acSAndroid Build Coastguard Worker   happening?  Since blocked threads just go away silently, it is hard to know
242*1c60b9acSAndroid Build Coastguard Worker   when in fact your thread is almost always blocked and not doing useful work.
243*1c60b9acSAndroid Build Coastguard Worker
244*1c60b9acSAndroid Build Coastguard Worker - threads require their own stack, which is on embedded is typically suffering
245*1c60b9acSAndroid Build Coastguard Worker   from a dedicated worst-case allocation where the headroom is usually idle
246*1c60b9acSAndroid Build Coastguard Worker
247*1c60b9acSAndroid Build Coastguard Worker - locking must be handled, and missed locking or lock order bugs found
248*1c60b9acSAndroid Build Coastguard Worker
249*1c60b9acSAndroid Build Coastguard Worker### But... what about latency if only one thing happens at a time?
250*1c60b9acSAndroid Build Coastguard Worker
251*1c60b9acSAndroid Build Coastguard Worker - Typically, at CPU speeds, nothing is happening at any given time on most
252*1c60b9acSAndroid Build Coastguard Worker   systems, the event loop is spending most of its time in the event wait
253*1c60b9acSAndroid Build Coastguard Worker   asleep at 0% cpu.
254*1c60b9acSAndroid Build Coastguard Worker
255*1c60b9acSAndroid Build Coastguard Worker - The POSIX sockets layer is disjoint from the actual network device driver.
256*1c60b9acSAndroid Build Coastguard Worker   It means that once you hand off the packet to the networking stack, the POSIX
257*1c60b9acSAndroid Build Coastguard Worker   api just returns and leaves the rest of the scheduling, retries etc to the
258*1c60b9acSAndroid Build Coastguard Worker   networking stack and device, descriptor queuing is driven by interrupts in
259*1c60b9acSAndroid Build Coastguard Worker   the driver part completely unaffected by the event loop part.
260*1c60b9acSAndroid Build Coastguard Worker
261*1c60b9acSAndroid Build Coastguard Worker - Passing data around via POSIX apis between the user code and the networking
262*1c60b9acSAndroid Build Coastguard Worker   stack tends to return almost immediately since its onward path is managed
263*1c60b9acSAndroid Build Coastguard Worker   later in another, usually interrupt, context.
264*1c60b9acSAndroid Build Coastguard Worker
265*1c60b9acSAndroid Build Coastguard Worker - So long as enough packets-worth of data are in the network stack ready to be
266*1c60b9acSAndroid Build Coastguard Worker   handed to descriptors, actual throughput is completely insensitive to jitter
267*1c60b9acSAndroid Build Coastguard Worker   or latency at the application event loop
268*1c60b9acSAndroid Build Coastguard Worker
269*1c60b9acSAndroid Build Coastguard Worker - The network device itself is inherently serializing packets, it can only send
270*1c60b9acSAndroid Build Coastguard Worker   one thing at a time.  The networking stack locking also introduces hidden
271*1c60b9acSAndroid Build Coastguard Worker   serialization by blocking multiple threads.
272*1c60b9acSAndroid Build Coastguard Worker
273*1c60b9acSAndroid Build Coastguard Worker - Many user systems are decoupled like the network stack and POSIX... the user
274*1c60b9acSAndroid Build Coastguard Worker   event loop and its latencies do not affect backend processes occurring in
275*1c60b9acSAndroid Build Coastguard Worker   interrupt or internal thread or other process contexts
276*1c60b9acSAndroid Build Coastguard Worker
277*1c60b9acSAndroid Build Coastguard Worker## Conclusion
278*1c60b9acSAndroid Build Coastguard Worker
279*1c60b9acSAndroid Build Coastguard WorkerEvent loops have been around for a very long time and are in wide use today due
280*1c60b9acSAndroid Build Coastguard Workerto their advantages.  Working with them successfully requires understand how to
281*1c60b9acSAndroid Build Coastguard Workeruse them and why they have the advantages and restrictions they do.
282*1c60b9acSAndroid Build Coastguard Worker
283*1c60b9acSAndroid Build Coastguard WorkerThe best results come from all the participants joining the same loop directly.
284*1c60b9acSAndroid Build Coastguard WorkerUsing a common event library in the participating codebases allows completely
285*1c60b9acSAndroid Build Coastguard Workerdifferent code can call each other's apis safely without locking.
286