|
160
|
1 Advanced event loops
|
|
|
2 ====================
|
|
|
3
|
|
|
4 libuv provides considerable user control over event loops, and you can achieve
|
|
|
5 interesting results by juggling multiple loops. You can also embed libuv's
|
|
|
6 event loop into another event loop based library -- imagine a Qt based UI, and
|
|
|
7 Qt's event loop driving a libuv backend which does intensive system level
|
|
|
8 tasks.
|
|
|
9
|
|
|
10 Stopping an event loop
|
|
|
11 ~~~~~~~~~~~~~~~~~~~~~~
|
|
|
12
|
|
|
13 ``uv_stop()`` can be used to stop an event loop. The earliest the loop will
|
|
|
14 stop running is *on the next iteration*, possibly later. This means that events
|
|
|
15 that are ready to be processed in this iteration of the loop will still be
|
|
|
16 processed, so ``uv_stop()`` can't be used as a kill switch. When ``uv_stop()``
|
|
|
17 is called, the loop **won't** block for i/o on this iteration. The semantics of
|
|
|
18 these things can be a bit difficult to understand, so let's look at
|
|
|
19 ``uv_run()`` where all the control flow occurs.
|
|
|
20
|
|
|
21 .. rubric:: src/unix/core.c - uv_run
|
|
|
22 .. literalinclude:: ../../../src/unix/core.c
|
|
|
23 :language: c
|
|
|
24 :linenos:
|
|
|
25 :lines: 304-324
|
|
|
26 :emphasize-lines: 10,19,21
|
|
|
27
|
|
|
28 ``stop_flag`` is set by ``uv_stop()``. Now all libuv callbacks are invoked
|
|
|
29 within the event loop, which is why invoking ``uv_stop()`` in them will still
|
|
|
30 lead to this iteration of the loop occurring. First libuv updates timers, then
|
|
|
31 runs pending timer, idle and prepare callbacks, and invokes any pending I/O
|
|
|
32 callbacks. If you were to call ``uv_stop()`` in any of them, ``stop_flag``
|
|
|
33 would be set. This causes ``uv_backend_timeout()`` to return ``0``, which is
|
|
|
34 why the loop does not block on I/O. If on the other hand, you called
|
|
|
35 ``uv_stop()`` in one of the check handlers, I/O has already finished and is not
|
|
|
36 affected.
|
|
|
37
|
|
|
38 ``uv_stop()`` is useful to shutdown a loop when a result has been computed or
|
|
|
39 there is an error, without having to ensure that all handlers are stopped one
|
|
|
40 by one.
|
|
|
41
|
|
|
42 Here is a simple example that stops the loop and demonstrates how the current
|
|
|
43 iteration of the loop still takes places.
|
|
|
44
|
|
|
45 .. rubric:: uvstop/main.c
|
|
|
46 .. literalinclude:: ../../code/uvstop/main.c
|
|
|
47 :language: c
|
|
|
48 :linenos:
|
|
|
49 :emphasize-lines: 11
|
|
|
50
|