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