1# Zircon Handles
2
3[TOC]
4
5## Basics
6Handles are kernel constructs that allows user-mode programs to
7reference a kernel object. A handle can be thought as a session
8or connection to a particular kernel object.
9
10It is often the case that multiple processes concurrently access
11the same object via different handles. However, a single handle
12can only be either bound to a single process or be bound to
13kernel.
14
15When it is bound to kernel we say it's 'in-transit'.
16
17In user-mode a handle is simply a specific number returned by
18some syscall. Only handles that are not in-transit are visible
19to user-mode.
20
21The integer that represents a handle is only meaningful for that
22process. The same number in another process might not map to any
23handle or it might map to a handle pointing to a completely
24different kernel object.
25
26The integer value for a handle is any 32-bit number except
27the value corresponding to ZX_HANDLE_INVALID.
28
29For kernel-mode, a handle is a C++ object that contains three
30logical fields:
31
32+ A reference to a kernel object
33+ The rights to the kernel object
34+ The process it is bound to (or if it's bound to kernel)
35
36The '[rights](rights.md)' specify what operations on the kernel object
37are allowed. It is possible for a single process to have two different
38handles to the same kernel object with different rights.
39
40## Using Handles
41There are many syscalls that create a new kernel object
42and which return a handle to it. To name a few:
43+ [`zx_event_create`](syscalls/event_create.md)
44+ [`zx_process_create`](syscalls/process_create.md)
45+ [`zx_thread_create`](syscalls/thread_create.md)
46
47These calls create both the kernel object and the first
48handle pointing to it. The handle is bound to the process that
49issued the syscall and the rights are the default rights for
50that type of kernel object.
51
52There is only one syscall that can make a copy of a handle,
53which points to the same kernel object and is bound to the same
54process that issued the syscall:
55+ [`zx_handle_duplicate`](syscalls/handle_duplicate.md)
56
57There is one syscall that creates an equivalent handle (possibly
58with fewer rights), invalidating the original handle:
59+ [`zx_handle_replace`](syscalls/handle_replace.md)
60
61There is one syscall that just destroys a handle:
62+ [`zx_handle_close`](syscalls/handle_close.md)
63
64There are two syscalls that takes a handle bound to calling
65process and binds it into kernel (puts the handle in-transit):
66+ [`zx_channel_write`](syscalls/channel_write.md)
67+ [`zx_socket_share`](syscalls/socket_share.md)
68
69There are three syscalls that takes an in-transit handle and
70binds it to the calling process:
71+ [`zx_channel_read`](syscalls/channel_read.md)
72+ [`zx_channel_call`](syscalls/channel_call.md)
73+ [`zx_socket_accept`](syscalls/socket_accept.md)
74
75The channel and socket syscalls above are used to transfer a handle from
76one process to another. For example it is possible to connect
77two processes with a channel. To transfer a handle the source process
78calls `zx_channel_write` or `zx_channel_call` and then the destination
79process calls `zx_channel_read` on the same channel.
80
81Finally, there is a single syscall that gives a new process its
82bootstrapping handle, that is, the handle that it can use to
83request other handles:
84+ [`zx_process_start`](syscalls/process_start.md)
85
86The bootstrapping handle can be of any transferable kernel object but
87the most reasonable case is that it points to one end of a channel
88so this initial channel can be used to send further handles into the
89new process.
90
91## Garbage Collection
92If a handle is valid, the kernel object it points to is guaranteed
93to be valid. This is ensured because kernel objects are ref-counted
94and each handle holds a reference to its kernel object.
95
96The opposite does not hold. When a handle is destroyed it does not
97mean its object is destroyed. There could be other handles pointing
98to the object or the kernel itself could be holding a reference to
99the kernel object. An example of this is a handle to a thread; the
100fact that the last handle to a thread is closed it does not mean that
101the thread has been terminated.
102
103When the last reference to a kernel object is released, the kernel
104object is either destroyed or the kernel marks the object for
105garbage collection; the object will be destroyed at a later time
106when the current set of pending operations on it are completed.
107
108## Special Cases
109+ When a handle is in-transit and the channel or socket it was written
110to is destroyed, the handle is closed.
111+ Debugging sessions (and debuggers) might have special syscalls to
112get access to handles.
113
114## Invalid Handles and handle reuse
115
116It is an error to pass to any syscall except for `zx_object_get_info`
117the following values:
118
119+ A handle value that corresponds to a closed handle
120+ The **ZX_HANDLE_INVALID** value, except for `zx_handle_close` syscall
121
122The kernel is free to re-use the integer values of closed handles for
123newly created objects. Therefore, it is important to make sure that proper
124handle hygiene is observed:
125
126+ Don't have one thread close a given handle and another thread use the
127  same handle in a racy way. Even if the second thread is also closing it.
128+ Don't ignore **ZX_ERR_BAD_HANDLE** return codes. They usually mean the
129  code has a logic error.
130
131Detecting invalid handle usage can be automated by using the
132**ZX_POL_BAD_HANDLE** Job policy with **ZX_POL_ACTION_EXCEPTION** to
133generate an exception when a process under such job object attempts any of
134the of the mentioned invalid cases.
135
136## See Also
137[Objects](objects.md),
138[Rights](rights.md)
139