annotate third_party/libuv/docs/src/guide/processes.rst @ 279:b3b547563ec7

Add Google connector service and agent wiki Implement the C/Seobeo Google Drive and Gmail connector with encrypted OAuth storage, Zenbu authentication, browser testing, AI tool discovery, chunked HTTP decoding, and Bazel coverage. Consolidate repository guidance into progressive wiki documentation and enforce arena-first allocation for new first-party C code. Co-authored-by: Copilot <[email protected]> Copilot-Session: 84c338fd-0939-4bb3-b7f3-1062eb213e5d
author MrJuneJune <me@mrjunejune.com>
date Mon, 17 Aug 2026 22:22:36 -0700
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 Processes
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
2 =========
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 libuv offers considerable child process management, abstracting the platform
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
5 differences and allowing communication with the child process using streams or
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
6 named pipes.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
7
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
8 A common idiom in Unix is for every process to do one thing and do it well. In
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
9 such a case, a process often uses multiple child processes to achieve tasks
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
10 (similar to using pipes in shells). A multi-process model with messages
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
11 may also be easier to reason about compared to one with threads and shared
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
12 memory.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
13
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
14 A common refrain against event-based programs is that they cannot take
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
15 advantage of multiple cores in modern computers. In a multi-threaded program
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
16 the kernel can perform scheduling and assign different threads to different
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
17 cores, improving performance. But an event loop has only one thread. The
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
18 workaround can be to launch multiple processes instead, with each process
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
19 running an event loop, and each process getting assigned to a separate CPU
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
20 core.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
21
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
22 Spawning child processes
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
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
25 The simplest case is when you simply want to launch a process and know when it
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
26 exits. This is achieved using ``uv_spawn``.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
27
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
28 .. rubric:: spawn/main.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
29 .. literalinclude:: ../../code/spawn/main.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
30 :language: c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
31 :linenos:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
32 :lines: 6-8,15-
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
33 :emphasize-lines: 11,13-17
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 .. NOTE::
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
36
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
37 ``options`` is implicitly initialized with zeros since it is a global
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
38 variable. If you change ``options`` to a local variable, remember to
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
39 initialize it to null out all unused fields::
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
40
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
41 uv_process_options_t options = {0};
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 ``uv_process_t`` struct only acts as the handle, all options are set via
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
44 ``uv_process_options_t``. To simply launch a process, you need to set only the
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
45 ``file`` and ``args`` fields. ``file`` is the program to execute. Since
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
46 ``uv_spawn`` uses :man:`execvp(3)` internally, there is no need to supply the full
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
47 path. Finally as per underlying conventions, **the arguments array has to be
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
48 one larger than the number of arguments, with the last element being NULL**.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
49
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
50 After the call to ``uv_spawn``, ``uv_process_t.pid`` will contain the process
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
51 ID of the child process.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
52
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
53 The exit callback will be invoked with the *exit status* and the type of *signal*
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
54 which caused the exit.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
55
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
56 Note that it is important **not** to call ``uv_close`` before the exit callback.
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 .. rubric:: spawn/main.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
59 .. literalinclude:: ../../code/spawn/main.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
60 :language: c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
61 :linenos:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
62 :lines: 9-12
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
63 :emphasize-lines: 3
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 It is **required** to close the process watcher after the process exits.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
66
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
67 Changing process parameters
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
68 ---------------------------
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
69
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
70 Before the child process is launched you can control the execution environment
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
71 using fields in ``uv_process_options_t``.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
72
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
73 Change execution directory
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
74 ++++++++++++++++++++++++++
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 Set ``uv_process_options_t.cwd`` to the corresponding directory.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
77
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
78 Set environment variables
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
79 +++++++++++++++++++++++++
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
80
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
81 ``uv_process_options_t.env`` is a null-terminated array of strings, each of the
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
82 form ``VAR=VALUE`` used to set up the environment variables for the process. Set
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
83 this to ``NULL`` to inherit the environment from the parent (this) process.
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 Option flags
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
86 ++++++++++++
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
87
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
88 Setting ``uv_process_options_t.flags`` to a bitwise OR of the following flags,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
89 modifies the child process behaviour:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
90
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
91 * ``UV_PROCESS_SETUID`` - sets the child's execution user ID to ``uv_process_options_t.uid``.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
92 * ``UV_PROCESS_SETGID`` - sets the child's execution group ID to ``uv_process_options_t.gid``.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
93
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
94 Changing the UID/GID is only supported on Unix, ``uv_spawn`` will fail on
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
95 Windows with ``UV_ENOTSUP``.
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 * ``UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS`` - No quoting or escaping of
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
98 ``uv_process_options_t.args`` is done on Windows. Ignored on Unix.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
99 * ``UV_PROCESS_DETACHED`` - Starts the child process in a new session, which
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
100 will keep running after the parent process exits. See example below.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
101
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
102 Detaching processes
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
103 -------------------
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 Passing the flag ``UV_PROCESS_DETACHED`` can be used to launch daemons, or
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
106 child processes which are independent of the parent so that the parent exiting
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
107 does not affect it.
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 .. rubric:: detach/main.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
110 .. literalinclude:: ../../code/detach/main.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
111 :language: c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
112 :linenos:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
113 :lines: 9-30
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
114 :emphasize-lines: 12,19
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
115
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
116 Just remember that the handle is still monitoring the child, so your program
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
117 won't exit. Use ``uv_unref()`` if you want to be more *fire-and-forget*.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
118
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
119 Sending signals to processes
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
120 ----------------------------
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 libuv wraps the standard ``kill(2)`` system call on Unix and implements one
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
123 with similar semantics on Windows, with *one caveat*: all of ``SIGTERM``,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
124 ``SIGINT`` and ``SIGKILL``, lead to termination of the process. The signature
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
125 of ``uv_kill`` is::
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
126
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
127 uv_err_t uv_kill(int pid, int signum);
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 processes started using libuv, you may use ``uv_process_kill`` instead,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
130 which accepts the ``uv_process_t`` watcher as the first argument, rather than
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
131 the pid. In this case, **remember to call** ``uv_close`` on the watcher _after_
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
132 the exit callback has been called.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
133
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
134 Signals
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
135 -------
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
136
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
137 libuv provides wrappers around Unix signals with `some Windows support
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
138 <http://docs.libuv.org/en/v1.x/signal.html#signal>`_ as well.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
139
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
140 Use ``uv_signal_init()`` to initialize
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
141 a handle and associate it with a loop. To listen for particular signals on
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
142 that handler, use ``uv_signal_start()`` with the handler function. Each handler
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
143 can only be associated with one signal number, with subsequent calls to
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
144 ``uv_signal_start()`` overwriting earlier associations. Use ``uv_signal_stop()`` to
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
145 stop watching. Here is a small example demonstrating the various possibilities:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
146
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
147 .. rubric:: signal/main.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
148 .. literalinclude:: ../../code/signal/main.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
149 :language: c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
150 :linenos:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
151 :emphasize-lines: 17-18,27-28
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
152
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
153 .. NOTE::
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
154
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
155 ``uv_run(loop, UV_RUN_NOWAIT)`` is similar to ``uv_run(loop, UV_RUN_ONCE)``
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
156 in that it will process only one event. UV_RUN_ONCE blocks if there are no
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
157 pending events, while UV_RUN_NOWAIT will return immediately. We use NOWAIT
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
158 so that one of the loops isn't starved because the other one has no pending
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
159 activity.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
160
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
161 Send ``SIGUSR1`` to the process, and you'll find the handler being invoked
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
162 4 times, one for each ``uv_signal_t``. The handler just stops each handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
163 so that the program exits. This sort of dispatch to all handlers is very
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
164 useful. A server using multiple event loops could ensure that all data was
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
165 safely saved before termination, simply by every loop adding a watcher for
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
166 ``SIGINT``.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
167
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
168 Child Process I/O
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
169 -----------------
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
170
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
171 A normal, newly spawned process has its own set of file descriptors, with 0,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
172 1 and 2 being ``stdin``, ``stdout`` and ``stderr`` respectively. Sometimes you
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
173 may want to share file descriptors with the child. For example, perhaps your
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
174 applications launches a sub-command and you want any errors to go in the log
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
175 file, but ignore ``stdout``. For this you'd like to have ``stderr`` of the
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
176 child be the same as the stderr of the parent. In this case, libuv supports
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
177 *inheriting* file descriptors. In this sample, we invoke the test program,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
178 which is:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
179
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
180 .. rubric:: proc-streams/test.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
181 .. literalinclude:: ../../code/proc-streams/test.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
182 :language: c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
183
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
184 The actual program ``proc-streams`` runs this while sharing only ``stderr``.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
185 The file descriptors of the child process are set using the ``stdio`` field in
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
186 ``uv_process_options_t``. First set the ``stdio_count`` field to the number of
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
187 file descriptors being set. ``uv_process_options_t.stdio`` is an array of
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
188 ``uv_stdio_container_t``, which is:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
189
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
190 .. code-block:: c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
191
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
192 typedef struct uv_stdio_container_s {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
193 uv_stdio_flags flags;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
194
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
195 union {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
196 uv_stream_t* stream;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
197 int fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
198 } data;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
199 } uv_stdio_container_t;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
200
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
201 where flags can have several values. Use ``UV_IGNORE`` if it isn't going to be
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
202 used. If the first three ``stdio`` fields are marked as ``UV_IGNORE`` they'll
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
203 redirect to ``/dev/null``.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
204
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
205 Since we want to pass on an existing descriptor, we'll use ``UV_INHERIT_FD``.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
206 Then we set the ``fd`` to ``stderr``.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
207
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
208 .. rubric:: proc-streams/main.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
209 .. literalinclude:: ../../code/proc-streams/main.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
210 :language: c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
211 :linenos:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
212 :lines: 15-17,27-
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
213 :emphasize-lines: 6,10,11,12
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
214
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
215 If you run ``proc-stream`` you'll see that only the line "This is stderr" will
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
216 be displayed. Try marking ``stdout`` as being inherited and see the output.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
217
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
218 It is dead simple to apply this redirection to streams. By setting ``flags``
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
219 to ``UV_INHERIT_STREAM`` and setting ``data.stream`` to the stream in the
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
220 parent process, the child process can treat that stream as standard I/O. This
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
221 can be used to implement something like CGI_.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
222
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
223 .. _CGI: https://en.wikipedia.org/wiki/Common_Gateway_Interface
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
224
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
225 A sample CGI script/executable is:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
226
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
227 .. rubric:: cgi/tick.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
228 .. literalinclude:: ../../code/cgi/tick.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
229 :language: c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
230
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
231 The CGI server combines the concepts from this chapter and :doc:`networking` so
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
232 that every client is sent ten ticks after which that connection is closed.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
233
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
234 .. rubric:: cgi/main.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
235 .. literalinclude:: ../../code/cgi/main.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
236 :language: c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
237 :linenos:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
238 :lines: 49-63
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
239 :emphasize-lines: 10
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
240
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
241 Here we simply accept the TCP connection and pass on the socket (*stream*) to
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
242 ``invoke_cgi_script``.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
243
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
244 .. rubric:: cgi/main.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
245 .. literalinclude:: ../../code/cgi/main.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
246 :language: c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
247 :linenos:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
248 :lines: 16, 25-45
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
249 :emphasize-lines: 8-9,18,20
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
250
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
251 The ``stdout`` of the CGI script is set to the socket so that whatever our tick
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
252 script prints, gets sent to the client. By using processes, we can offload the
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
253 read/write buffering to the operating system, so in terms of convenience this
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
254 is great. Just be warned that creating processes is a costly task.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
255
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
256 .. _pipes:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
257
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
258 Parent-child IPC
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
259 ----------------
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
260
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
261 A parent and child can have one or two way communication over a pipe created by
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
262 settings ``uv_stdio_container_t.flags`` to a bit-wise combination of
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
263 ``UV_CREATE_PIPE`` and ``UV_READABLE_PIPE`` or ``UV_WRITABLE_PIPE``. The
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
264 read/write flag is from the perspective of the child process. In this case,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
265 the ``uv_stream_t* stream`` field must be set to point to an initialized,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
266 unopened ``uv_pipe_t`` instance.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
267
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
268 New stdio Pipes
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
269 +++++++++++++++
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
270
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
271 The ``uv_pipe_t`` structure represents more than just `pipe(7)`_ (or ``|``),
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
272 but supports any streaming file-like objects. On Windows, the only object of
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
273 that description is the `Named Pipe`_. On Unix, this could be any of `Unix
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
274 Domain Socket`_, or derived from `mkfifo(1)`_, or it could actually be a
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
275 `pipe(7)`_. When ``uv_spawn`` initializes a ``uv_pipe_t`` due to the
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
276 `UV_CREATE_PIPE` flag, it opts for creating a `socketpair(2)`_.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
277
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
278 This is intended for the purpose of allowing multiple libuv processes to
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
279 communicate with IPC. This is discussed below.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
280
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
281 .. _pipe(7): https://man7.org/linux/man-pages/man7/pipe.7.html
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
282 .. _mkfifo(1): https://man7.org/linux/man-pages/man1/mkfifo.1.html
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
283 .. _socketpair(2): https://man7.org/linux/man-pages/man2/socketpair.2.html
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
284 .. _Unix Domain Socket: https://man7.org/linux/man-pages/man7/unix.7.html
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
285 .. _Named Pipe: https://docs.microsoft.com/en-us/windows/win32/ipc/named-pipes
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
286
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
287
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
288 Arbitrary process IPC
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
289 +++++++++++++++++++++
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
290
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
291 Since domain sockets [#]_ can have a well known name and a location in the
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
292 file-system they can be used for IPC between unrelated processes. The D-BUS_
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
293 system used by open source desktop environments uses domain sockets for event
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
294 notification. Various applications can then react when a contact comes online
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
295 or new hardware is detected. The MySQL server also runs a domain socket on
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
296 which clients can interact with it.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
297
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
298 .. _D-BUS: https://www.freedesktop.org/wiki/Software/dbus
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
299
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
300 When using domain sockets, a client-server pattern is usually followed with the
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
301 creator/owner of the socket acting as the server. After the initial setup,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
302 messaging is no different from TCP, so we'll re-use the echo server example.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
303
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
304 .. rubric:: pipe-echo-server/main.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
305 .. literalinclude:: ../../code/pipe-echo-server/main.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
306 :language: c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
307 :linenos:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
308 :lines: 70-
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
309 :emphasize-lines: 5,10,14
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
310
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
311 We name the socket ``echo.sock`` which means it will be created in the local
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
312 directory. This socket now behaves no different from TCP sockets as far as
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
313 the stream API is concerned. You can test this server using `socat`_::
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
314
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
315 $ socat - /path/to/socket
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
316
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
317 A client which wants to connect to a domain socket will use::
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
318
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
319 void uv_pipe_connect(uv_connect_t *req, uv_pipe_t *handle, const char *name, uv_connect_cb cb);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
320
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
321 where ``name`` will be ``echo.sock`` or similar. On Unix systems, ``name`` must
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
322 point to a valid file (e.g. ``/tmp/echo.sock``). On Windows, ``name`` follows a
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
323 ``\\?\pipe\echo.sock`` format.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
324
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
325 .. _socat: http://www.dest-unreach.org/socat/
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
326
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
327 Sending file descriptors over pipes
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
328 +++++++++++++++++++++++++++++++++++
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
329
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
330 The cool thing about domain sockets is that file descriptors can be exchanged
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
331 between processes by sending them over a domain socket. This allows processes
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
332 to hand off their I/O to other processes. Applications include load-balancing
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
333 servers, worker processes and other ways to make optimum use of CPU. libuv only
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
334 supports sending **TCP sockets or other pipes** over pipes for now.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
335
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
336 To demonstrate, we will look at an echo server implementation that hands off
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
337 clients to worker processes in a round-robin fashion. This program is a bit
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
338 involved, and while only snippets are included in the book, it is recommended
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
339 to read the full code to really understand it.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
340
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
341 The worker process is quite simple, since the file-descriptor is handed over to
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
342 it by the master.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
343
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
344 .. rubric:: multi-echo-server/worker.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
345 .. literalinclude:: ../../code/multi-echo-server/worker.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
346 :language: c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
347 :linenos:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
348 :lines: 7-9,81-
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
349 :emphasize-lines: 6-8
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
350
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
351 ``queue`` is the pipe connected to the master process on the other end, along
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
352 which new file descriptors get sent. It is important to set the ``ipc``
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
353 argument of ``uv_pipe_init`` to 1 to indicate this pipe will be used for
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
354 inter-process communication! Since the master will write the file handle to the
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
355 standard input of the worker, we connect the pipe to ``stdin`` using
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
356 ``uv_pipe_open``.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
357
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
358 .. rubric:: multi-echo-server/worker.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
359 .. literalinclude:: ../../code/multi-echo-server/worker.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
360 :language: c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
361 :linenos:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
362 :lines: 51-79
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
363 :emphasize-lines: 10,15,20
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
364
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
365 First we call ``uv_pipe_pending_count()`` to ensure that a handle is available
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
366 to read out. If your program could deal with different types of handles,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
367 ``uv_pipe_pending_type()`` can be used to determine the type.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
368 Although ``accept`` seems odd in this code, it actually makes sense. What
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
369 ``accept`` traditionally does is get a file descriptor (the client) from
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
370 another file descriptor (The listening socket). Which is exactly what we do
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
371 here. Fetch the file descriptor (``client``) from ``queue``. From this point
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
372 the worker does standard echo server stuff.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
373
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
374 Turning now to the master, let's take a look at how the workers are launched to
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
375 allow load balancing.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
376
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
377 .. rubric:: multi-echo-server/main.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
378 .. literalinclude:: ../../code/multi-echo-server/main.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
379 :language: c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
380 :linenos:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
381 :lines: 9-13
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
382
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
383 The ``child_worker`` structure wraps the process, and the pipe between the
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
384 master and the individual process.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
385
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
386 .. rubric:: multi-echo-server/main.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
387 .. literalinclude:: ../../code/multi-echo-server/main.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
388 :language: c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
389 :linenos:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
390 :lines: 51,61-95
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
391 :emphasize-lines: 17,20-21
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
392
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
393 In setting up the workers, we use the nifty libuv function ``uv_cpu_info`` to
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
394 get the number of CPUs so we can launch an equal number of workers. Again it is
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
395 important to initialize the pipe acting as the IPC channel with the third
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
396 argument as 1. We then indicate that the child process' ``stdin`` is to be
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
397 a readable pipe (from the point of view of the child). Everything is
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
398 straightforward till here. The workers are launched and waiting for file
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
399 descriptors to be written to their standard input.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
400
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
401 It is in ``on_new_connection`` (the TCP infrastructure is initialized in
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
402 ``main()``), that we accept the client socket and pass it along to the next
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
403 worker in the round-robin.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
404
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
405 .. rubric:: multi-echo-server/main.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
406 .. literalinclude:: ../../code/multi-echo-server/main.c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
407 :language: c
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
408 :linenos:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
409 :lines: 31-49
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
410 :emphasize-lines: 9,12-13
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
411
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
412 The ``uv_write2`` call handles all the abstraction and it is simply a matter of
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
413 passing in the handle (``client``) as the right argument. With this our
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
414 multi-process echo server is operational.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
415
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
416 Thanks to Kyle for `pointing out`_ that ``uv_write2()`` requires a non-empty
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
417 buffer even when sending handles.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
418
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
419 .. _pointing out: https://github.com/nikhilm/uvbook/issues/56
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
420
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
421 ----
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
422
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
423 .. [#] In this section domain sockets stands in for named pipes on Windows as
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
424 well.