annotate third_party/libuv/docs/src/design.rst @ 175:71ad34a8bc9a hg-web

[HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
author MrJuneJune <me@mrjunejune.com>
date Tue, 20 Jan 2026 06:06:47 -0800
parents 948de3f54cea
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
160
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
2 .. _design:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
3
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
4 Design overview
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
5 ===============
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
6
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
7 libuv is cross-platform support library which was originally written for `Node.js`_. It's designed
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
8 around the event-driven asynchronous I/O model.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
9
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
10 .. _Node.js: https://nodejs.org
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
11
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
12 The library provides much more than a simple abstraction over different I/O polling mechanisms:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
13 'handles' and 'streams' provide a high level abstraction for sockets and other entities;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
14 cross-platform file I/O and threading functionality is also provided, amongst other things.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
15
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
16 Here is a diagram illustrating the different parts that compose libuv and what subsystem they
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
17 relate to:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
18
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
19 .. image:: static/architecture.png
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
20 :scale: 75%
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
21 :align: center
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
22
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
23
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
24 Handles and requests
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
25 ^^^^^^^^^^^^^^^^^^^^
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
26
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
27 libuv provides users with 2 abstractions to work with, in combination with the event loop:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
28 handles and requests.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
29
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
30 Handles represent long-lived objects capable of performing certain operations while active. Some examples:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
31
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
32 - A prepare handle gets its callback called once every loop iteration when active.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
33 - A TCP server handle that gets its connection callback called every time there is a new connection.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
34
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
35 Requests represent (typically) short-lived operations. These operations can be performed over a
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
36 handle: write requests are used to write data on a handle; or standalone: getaddrinfo requests
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
37 don't need a handle they run directly on the loop.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
38
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
39
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
40 The I/O loop
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
41 ^^^^^^^^^^^^
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
42
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
43 The I/O (or event) loop is the central part of libuv. It establishes the content for all I/O
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
44 operations, and it's meant to be tied to a single thread. One can run multiple event loops
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
45 as long as each runs in a different thread. The libuv event loop (or any other API involving
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
46 the loop or handles, for that matter) **is not thread-safe** except where stated otherwise.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
47
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
48 The event loop follows the rather usual single threaded asynchronous I/O approach: all (network)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
49 I/O is performed on non-blocking sockets which are polled using the best mechanism available
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
50 on the given platform: epoll on Linux, kqueue on OSX and other BSDs, event ports on SunOS and IOCP
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
51 on Windows. As part of a loop iteration the loop will block waiting for I/O activity on sockets
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
52 which have been added to the poller and callbacks will be fired indicating socket conditions
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
53 (readable, writable hangup) so handles can read, write or perform the desired I/O operation.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
54
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
55 In order to better understand how the event loop operates, the following diagram illustrates all
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
56 stages of a loop iteration:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
57
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
58 .. image:: static/loop_iteration.png
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
59 :scale: 75%
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
60 :align: center
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
61
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
62
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
63 #. The loop concept of 'now' is initially set.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
64
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
65 #. Due timers are run if the loop was run with ``UV_RUN_DEFAULT``. All active timers scheduled
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
66 for a time before the loop's concept of *now* get their callbacks called.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
67
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
68 #. If the loop is *alive* an iteration is started, otherwise the loop will exit immediately. So,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
69 when is a loop considered to be *alive*? If a loop has active and ref'd handles, active
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
70 requests or closing handles it's considered to be *alive*.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
71
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
72 #. Pending callbacks are called. All I/O callbacks are called right after polling for I/O, for the
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
73 most part. There are cases, however, in which calling such a callback is deferred for the next
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
74 loop iteration. If the previous iteration deferred any I/O callback it will be run at this point.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
75
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
76 #. Idle handle callbacks are called. Despite the unfortunate name, idle handles are run on every
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
77 loop iteration, if they are active.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
78
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
79 #. Prepare handle callbacks are called. Prepare handles get their callbacks called right before
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
80 the loop will block for I/O.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
81
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
82 #. Poll timeout is calculated. Before blocking for I/O the loop calculates for how long it should
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
83 block. These are the rules when calculating the timeout:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
84
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
85 * If the loop was run with the ``UV_RUN_NOWAIT`` flag, the timeout is 0.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
86 * If the loop is going to be stopped (:c:func:`uv_stop` was called), the timeout is 0.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
87 * If there are no active handles or requests, the timeout is 0.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
88 * If there are any idle handles active, the timeout is 0.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
89 * If there are any handles pending to be closed, the timeout is 0.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
90 * If none of the above cases matches, the timeout of the closest timer is taken, or
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
91 if there are no active timers, infinity.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
92
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
93 #. The loop blocks for I/O. At this point the loop will block for I/O for the duration calculated
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
94 in the previous step. All I/O related handles that were monitoring a given file descriptor
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
95 for a read or write operation get their callbacks called at this point.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
96
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
97 #. Check handle callbacks are called. Check handles get their callbacks called right after the
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
98 loop has blocked for I/O. Check handles are essentially the counterpart of prepare handles.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
99
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
100 #. Close callbacks are called. If a handle was closed by calling :c:func:`uv_close` it will
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
101 get the close callback called.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
102
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
103 #. The loop concept of 'now' is updated.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
104
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
105 #. Due timers are run. Note that 'now' is not updated again until the next loop iteration.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
106 So if a timer became due while other timers were being processed, it won't be run until
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
107 the following event loop iteration.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
108
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
109 #. Iteration ends. If the loop was run with ``UV_RUN_NOWAIT`` or ``UV_RUN_ONCE`` modes the
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
110 iteration ends and :c:func:`uv_run` will return. If the loop was run with ``UV_RUN_DEFAULT``
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
111 it will continue from the start if it's still *alive*, otherwise it will also end.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
112
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
113
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
114 .. important::
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
115 libuv uses a thread pool to make asynchronous file I/O operations possible, but
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
116 network I/O is **always** performed in a single thread, each loop's thread.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
117
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
118 .. note::
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
119 While the polling mechanism is different, libuv makes the execution model consistent
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
120 across Unix systems and Windows.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
121
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
122
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
123 File I/O
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
124 ^^^^^^^^
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
125
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
126 Unlike network I/O, there are no platform-specific file I/O primitives libuv could rely on,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
127 so the current approach is to run blocking file I/O operations in a thread pool.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
128
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
129 For a thorough explanation of the cross-platform file I/O landscape, check out
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
130 `this post <https://blog.libtorrent.org/2012/10/asynchronous-disk-io/>`_.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
131
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
132 libuv currently uses a global thread pool on which all loops can queue work. 3 types of
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
133 operations are currently run on this pool:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
134
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
135 * File system operations
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
136 * DNS functions (getaddrinfo and getnameinfo)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
137 * User specified code via :c:func:`uv_queue_work`
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
138
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
139 .. warning::
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
140 See the :c:ref:`threadpool` section for more details, but keep in mind the thread pool size
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
141 is quite limited.