Skip to main content

fdf_sys/
bindings.rs

1// Copyright 2024 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// This file is automatically generated by //sdk/lib/driver/runtime/rust/fdf_sys:fdf_sys_bindgen_golden.
6
7#![expect(non_camel_case_types)]
8
9use libasync_sys::*;
10use zx_types::*;
11
12pub type fdf_handle_t = zx_handle_t;
13pub type fdf_txid_t = zx_txid_t;
14#[repr(C)]
15#[derive(Debug)]
16pub struct fdf_arena {
17    _unused: [u8; 0],
18}
19#[repr(C)]
20#[derive(Debug, Copy, Clone)]
21pub struct fdf_channel_call_args {
22    pub wr_arena: *mut fdf_arena,
23    pub wr_data: *mut ::core::ffi::c_void,
24    pub wr_num_bytes: u32,
25    pub wr_handles: *mut zx_handle_t,
26    pub wr_num_handles: u32,
27    pub rd_arena: *mut *mut fdf_arena,
28    pub rd_data: *mut *mut ::core::ffi::c_void,
29    pub rd_num_bytes: *mut u32,
30    pub rd_handles: *mut *mut zx_handle_t,
31    pub rd_num_handles: *mut u32,
32}
33#[allow(clippy::unnecessary_operation, clippy::identity_op)]
34const _: () = {
35    ["Size of fdf_channel_call_args"][::core::mem::size_of::<fdf_channel_call_args>() - 80usize];
36    ["Alignment of fdf_channel_call_args"]
37        [::core::mem::align_of::<fdf_channel_call_args>() - 8usize];
38    ["Offset of field: fdf_channel_call_args::wr_arena"]
39        [::core::mem::offset_of!(fdf_channel_call_args, wr_arena) - 0usize];
40    ["Offset of field: fdf_channel_call_args::wr_data"]
41        [::core::mem::offset_of!(fdf_channel_call_args, wr_data) - 8usize];
42    ["Offset of field: fdf_channel_call_args::wr_num_bytes"]
43        [::core::mem::offset_of!(fdf_channel_call_args, wr_num_bytes) - 16usize];
44    ["Offset of field: fdf_channel_call_args::wr_handles"]
45        [::core::mem::offset_of!(fdf_channel_call_args, wr_handles) - 24usize];
46    ["Offset of field: fdf_channel_call_args::wr_num_handles"]
47        [::core::mem::offset_of!(fdf_channel_call_args, wr_num_handles) - 32usize];
48    ["Offset of field: fdf_channel_call_args::rd_arena"]
49        [::core::mem::offset_of!(fdf_channel_call_args, rd_arena) - 40usize];
50    ["Offset of field: fdf_channel_call_args::rd_data"]
51        [::core::mem::offset_of!(fdf_channel_call_args, rd_data) - 48usize];
52    ["Offset of field: fdf_channel_call_args::rd_num_bytes"]
53        [::core::mem::offset_of!(fdf_channel_call_args, rd_num_bytes) - 56usize];
54    ["Offset of field: fdf_channel_call_args::rd_handles"]
55        [::core::mem::offset_of!(fdf_channel_call_args, rd_handles) - 64usize];
56    ["Offset of field: fdf_channel_call_args::rd_num_handles"]
57        [::core::mem::offset_of!(fdf_channel_call_args, rd_num_handles) - 72usize];
58};
59impl Default for fdf_channel_call_args {
60    fn default() -> Self {
61        let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
62        unsafe {
63            ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
64            s.assume_init()
65        }
66    }
67}
68pub type fdf_channel_call_args_t = fdf_channel_call_args;
69#[doc = " This flag will prevent any dispatchers from being created on the role that allow sync calls."]
70pub const FDF_SCHEDULER_ROLE_OPTION_NO_SYNC_CALLS: u32 = 1;
71#[doc = " This flag disallows parallel calls into callbacks set in the dispatcher."]
72pub const FDF_DISPATCHER_OPTION_SYNCHRONIZED: u32 = 0;
73#[doc = " This flag allows parallel calls into callbacks set in the dispatcher.\n Cannot be set in conjunction with `FDF_DISPATCHER_OPTION_ALLOW_SYNC_CALLS`."]
74pub const FDF_DISPATCHER_OPTION_UNSYNCHRONIZED: u32 = 1;
75#[doc = " This flag indicates that the dispatcher may not share zircon threads with other drivers.\n Cannot be set in conjunction with `FDF_DISPATCHER_OPTION_UNSYNCHRONIZED`."]
76pub const FDF_DISPATCHER_OPTION_ALLOW_SYNC_CALLS: u32 = 2;
77#[doc = " This flag indicates that the dispatcher must not have its thread migrated at\n runtime. It can only be used if the dispatcher's scheduler role has the\n `FDF_SCHEDULER_ROLE_OPTION_NO_SYNC_CALLS` option set."]
78pub const FDF_DISPATCHER_OPTION_NO_THREAD_MIGRATION: u32 = 4;
79pub const FDF_DISPATCHER_OPTION_SYNCHRONIZATION_MASK: u32 = 1;
80#[doc = " This flag forces a channel wait to call its callback on cancellation,\n even if the wait starts on a synchronized dispatcher. This allows\n for safe cancellation of the wait from a different dispatcher than the one\n it started on."]
81pub const FDF_CHANNEL_WAIT_OPTION_FORCE_ASYNC_CANCEL: u32 = 1;
82#[doc = " This flag indicates that the channel wait was scheduled on an always-on\n dispatcher."]
83pub const FDF_CHANNEL_WAIT_OPTION_ALWAYS_ON: u32 = 2;
84#[doc = " An arena which supports allocation of memory.\n\n The arena owns all the allocated memory. Individual memory allocations can be freed\n by calling |fdf_arena_free|, or will be freed when all references to the underlying\n runtime arena object are destroyed.\n\n |fdf_arena_create| will return a reference to a newly created runtime arena object.\n Passing an arena to |fdf_channel_write| will create and transfer a new reference to\n that same arena, and does not take ownership of your arena reference. The reference\n may be destroyed using |fdf_arena_drop_ref|.\n\n # Thread safety\n\n Operations on arena objects are thread-safe.\n\n # Example\n\n   fdf_arena_t* arena;\n   zx_status_t status = fdf_arena_create(0, 'exam', 0, &arena);\n\n   // Allocate new blocks of memory.\n   void* addr1 = fdf_arena_allocate(arena, 0x1000);\n   void* addr2 = fdf_arena_allocate(arena, 0x2000);\n\n   // Use the allocated memory...\n\n   fdf_arena_drop_ref(arena);"]
85pub type fdf_arena_t = fdf_arena;
86pub type fdf_arena_tag_t = u32;
87unsafe extern "C" {
88    #[doc = " Creates a FDF arena for allocating memory.\n\n |tag| provides a hint to the runtime so that it may be more efficient.\n For example, adjusting the size of the buffer backing the arena to the expected\n total size of allocations. It may also be surfaced in debug information.\n\n # Errors\n\n ZX_ERR_INVALID_ARGS: |options| is any value other than 0.\n\n ZX_ERR_NO_MEMORY: Failed due to a lack of memory."]
89    pub fn fdf_arena_create(
90        options: u32,
91        tag: fdf_arena_tag_t,
92        out_arena: *mut *mut fdf_arena_t,
93    ) -> zx_status_t;
94}
95unsafe extern "C" {
96    #[doc = " Returns a pointer to allocated memory of size |bytes|. The memory is managed by the arena\n until it is freed by |fdf_arena_free|, or the arena is destroyed once every reference to\n the arena hss been destroyed using |fdf_arena_drop_ref|."]
97    pub fn fdf_arena_allocate(arena: *mut fdf_arena_t, bytes: usize) -> *mut ::core::ffi::c_void;
98}
99unsafe extern "C" {
100    #[doc = " Hints to the arena that the |ptr| previously allocated by |fdf_arena_allocate| may be reclaimed.\n Memory is not guaranteed to be reclaimed until |fdf_arena_drop_ref| is invoked.\n Asserts if the memory is not managed by the arena."]
101    pub fn fdf_arena_free(arena: *mut fdf_arena_t, ptr: *mut ::core::ffi::c_void);
102}
103unsafe extern "C" {
104    #[doc = " Returns whether the memory region consisting of [|ptr|, |ptr|+|num_bytes|) resides entirely\n within memory managed by the |arena|."]
105    pub fn fdf_arena_contains(
106        arena: *mut fdf_arena_t,
107        ptr: *const ::core::ffi::c_void,
108        num_bytes: usize,
109    ) -> bool;
110}
111unsafe extern "C" {
112    #[doc = " Increments the reference count to the underlying runtime arena object.\n This is intended mostly for use with FFIs, such as for Rust, to enable\n more ergonomic use. Users in C should not need to call this, as\n the reference count will be properly managed with the `fdf_channel_*`\n and `fdf_arena_drop_ref` functions.\n Calls to this function must be balanced by corresponding calls to\n `fdf_arena_drop_ref`."]
113    pub fn fdf_arena_add_ref(arena: *mut fdf_arena_t);
114}
115unsafe extern "C" {
116    #[doc = " Destroys the reference to the underlying runtime arena object.\n If there are no more references to the arena, all memory associated with\n the arena will be freed."]
117    pub fn fdf_arena_drop_ref(arena: *mut fdf_arena_t);
118}
119#[repr(C)]
120#[derive(Debug)]
121pub struct fdf_dispatcher {
122    _unused: [u8; 0],
123}
124#[doc = " Dispatcher for performing asynchronous operations.\n\n |fdf_dispatcher_t| can be used in conjunction with a |fdf_channel_t|\n to initiate asynchronous read operations. The dispatcher is in\n charge of dispatching the read callbacks.\n\n # Thread safety\n\n Operations on dispatcher objects are thread-safe.\n\n # Example\n\n   void shutdown_handler(fdf_dispatcher_t* dispatcher,\n                         fdf_dispatcher_shutdown_observer_t* fdf_observer) {\n     // Handle dispatcher shutdown.\n     // It is now safe to destroy |dispatcher|.\n   }\n\n   struct dispatcher_shutdown_observer {\n     fdf_dispatcher_shutdown_observer_t fdf_observer;\n     my_ctx* ctx;\n   };\n\n   void driver_start(void) {\n     const char* name = \"my_driver\";\n     const char* scheduler_role = \"\";\n     struct dispatcher_shutdown_observer my_observer;\n     my_observer.fdf_observer.handler = shutdown_handler;\n     ...\n\n     fdf_dispatcher_t* dispatcher;\n     zx_status_t status = fdf_dispatcher_create(0, name, strlen(name),\n                                                scheduler_role, strlen(scheduler_role),\n                                                &my_observer.fdf_observer, &dispatcher);\n\n     fdf_channel_read_t channel_read;\n     ...\n     status = fdf_channel_wait_async(dispatcher, channel_read, 0);\n\n     // The dispatcher will call the channel_read handler when ready.\n\n     // This begins the dispatcher shutdown process.\n     fdf_dispatcher_shutdown_async(dispatcher);\n   }"]
125pub type fdf_dispatcher_t = fdf_dispatcher;
126#[doc = " Holds context for the observer which will be called when the dispatcher's\n asynchronous shutdown has completed.\n\n After creating the dispatcher, the client is responsible for retaining\n this structure in memory (and unmodified) until the handler runs."]
127pub type fdf_dispatcher_shutdown_observer_t = fdf_dispatcher_shutdown_observer;
128#[doc = " Called when the asynchronous shutdown for |dispatcher| has completed."]
129pub type fdf_dispatcher_shutdown_handler_t = ::core::option::Option<
130    unsafe extern "C" fn(
131        dispatcher: *mut fdf_dispatcher_t,
132        observer: *mut fdf_dispatcher_shutdown_observer_t,
133    ),
134>;
135#[doc = " Holds context for the observer which will be called when the dispatcher's\n asynchronous shutdown has completed.\n\n After creating the dispatcher, the client is responsible for retaining\n this structure in memory (and unmodified) until the handler runs."]
136#[repr(C)]
137#[derive(Debug, Default, Copy, Clone)]
138pub struct fdf_dispatcher_shutdown_observer {
139    pub handler: fdf_dispatcher_shutdown_handler_t,
140}
141#[allow(clippy::unnecessary_operation, clippy::identity_op)]
142const _: () = {
143    ["Size of fdf_dispatcher_shutdown_observer"]
144        [::core::mem::size_of::<fdf_dispatcher_shutdown_observer>() - 8usize];
145    ["Alignment of fdf_dispatcher_shutdown_observer"]
146        [::core::mem::align_of::<fdf_dispatcher_shutdown_observer>() - 8usize];
147    ["Offset of field: fdf_dispatcher_shutdown_observer::handler"]
148        [::core::mem::offset_of!(fdf_dispatcher_shutdown_observer, handler) - 0usize];
149};
150unsafe extern "C" {
151    #[doc = " Creates a dispatcher for performing asynchronous operations.\n\n |options| provides the dispatcher configuration. The following options are supported:\n   * `FDF_DISPATHER_OPTION_SYNCHRONIZED` or `FDF_DISPATCHER_OPTION_UNSYNCHRONIZED` - sets whether\n     parallel callbacks in the callbacks set in the dispatcher are allowed.\n   * `FDF_DISPATCHER_OPTION_ALLOW_SYNC_CALLS` - the dispatcher may not share zircon threads with\n     other drivers. This may not be set with `FDF_DISPATCHER_OPTION_UNSYNCHRONIZED` or on a\n     scheduler role that has `FDF_SCHEDULER_ROLE_OPTION_NO_SYNC_CALLS` set on it.\n\n |name| is reported via diagnostics. It is similar to setting the name of a thread.\n |name_len| is the length of the string, without including the terminated NULL character. If\n |name| is greater than `ZX_MAX_NAME_LEN`, the length may be truncated.\n\n |scheduler_role| is a hint. It may or not impact the priority the work scheduler against the\n dispatcher is handled at. It may or may not impact the ability for other drivers to share zircon\n threads with the dispatcher.\n |scheduler_role_len | is the length of the string, without including the terminating\n NULL character.\n\n |observer| will be called after |fdf_dispatcher_shutdown_async| has been called,\n and the dispatcher has completed its asynchronous shutdown.\n\n # Thread requirements\n\n This must be called from a thread managed by the driver runtime.\n\n # Errors\n\n ZX_ERR_NOT_SUPPORTED: |options| is not a supported configuration, which is any of the following:\n   * `FDF_DISPATCHER_OPTION_UNSYNCHRONIZED` with `FDF_DISPATCHER_OPTION_ALLOW_SYNC_CALLS`.\n\n ZX_ERR_INVALID_ARGS: This was not called from a thread managed by the driver runtime.\n\n ZX_ERR_NO_RESOURCES: A thread needed to be spawned to create this dispatcher, but couldn't be.\n This is likely because a dispatcher that allows sync calls was requested, but the thread pool is\n currently at its limit.\n\n ZX_ERR_BAD_STATE: Dispatchers are currently not allowed to be created, such as when a driver\n is being shutdown by its driver host."]
152    pub fn fdf_dispatcher_create(
153        options: u32,
154        name: *const ::core::ffi::c_char,
155        name_len: usize,
156        scheduler_role: *const ::core::ffi::c_char,
157        scheduler_role_len: usize,
158        observer: *mut fdf_dispatcher_shutdown_observer_t,
159        out_dispatcher: *mut *mut fdf_dispatcher_t,
160    ) -> zx_status_t;
161}
162unsafe extern "C" {
163    #[doc = " Returns the asynchronous dispatch interface."]
164    pub fn fdf_dispatcher_get_async_dispatcher(
165        dispatcher: *mut fdf_dispatcher_t,
166    ) -> *mut async_dispatcher_t;
167}
168unsafe extern "C" {
169    #[doc = " Returns an unowned dispatcher provided an async dispatcher. If |async_dispatcher| was not\n retrieved via |fdf_dispatcher_get_async_dispatcher|, the call will result in a crash."]
170    pub fn fdf_dispatcher_downcast_async_dispatcher(
171        async_dispatcher: *mut async_dispatcher_t,
172    ) -> *mut fdf_dispatcher_t;
173}
174unsafe extern "C" {
175    #[doc = " Returns the current thread's dispatcher.\n This will return NULL if not called from a dispatcher managed thread."]
176    pub fn fdf_dispatcher_get_current_dispatcher() -> *mut fdf_dispatcher_t;
177}
178unsafe extern "C" {
179    #[doc = " Returns the options set for this dispatcher."]
180    pub fn fdf_dispatcher_get_options(dispatcher: *const fdf_dispatcher_t) -> u32;
181}
182unsafe extern "C" {
183    #[doc = " Begins shutting down the dispatcher. Shutting down is an asynchronous operation.\n\n Once |fdf_dispatcher_shutdown_async| is called, the dispatcher will no longer\n accept queueing new |async_dispatcher_t| operations or |ChannelRead| callbacks.\n\n The dispatcher will asynchronously wait for all pending |async_dispatcher_t|\n and |ChannelRead| callbacks to complete. Then it will serially cancel all\n remaining callbacks with |ZX_ERR_CANCELED| and call the shutdown handler set\n in |fdf_dispatcher_create|.\n\n If the dispatcher is already shutting down or has completed shutdown, this will do nothing."]
184    pub fn fdf_dispatcher_shutdown_async(dispatcher: *mut fdf_dispatcher_t);
185}
186unsafe extern "C" {
187    #[doc = " Informs the runtime that |dispatcher| may be destroyed.\n\n The dispatcher must be completely shutdown before this is called,\n i.e. the shutdown handler set in |fdf_dispatcher_create| has been called.\n It is safe to call this from that shutdown handler.\n\n |dispatcher| must not be used after calling this function."]
188    pub fn fdf_dispatcher_destroy(dispatcher: *mut fdf_dispatcher_t);
189}
190unsafe extern "C" {
191    #[doc = " Removes an option set on the dispatcher during creation. The provided |option| parameter\n is removed from the |dispatcher| given. For example if the dispatcher was created with options\n that contained `FDF_DISPATCHER_OPTION_ALLOW_SYNC_CALLS`, calling this with that option will\n remove the ability of the dispatcher to make any more synchronous calls.\n\n The following options are supported for sealing (aka removal):\n  - `FDF_DISPATCHER_OPTION_ALLOW_SYNC_CALLS`\n\n # Thread requirements\n\n This must be called from the |dispatcher|'s own context.\n\n # Errors\n\n ZX_ERR_INVALID_ARGS: The |option| being removed is not a supported option.\n\n ZX_ERR_BAD_STATE: Not called from the same context as the given dispatcher or the dispatcher\n is not in a running state.\n\n ZX_ERR_ALREADY_EXISTS: The option did not exist on the dispatcher. This can happen if this is\n called more than once with the same option, or if it was not created with the option."]
192    pub fn fdf_dispatcher_seal(dispatcher: *mut fdf_dispatcher_t, option: u32) -> zx_status_t;
193}
194unsafe extern "C" {
195    #[doc = " Returns the always-on dispatcher interface for the given dispatcher.\n\n The primary user of this is the driver's fuchsia.driver.framework/Driver FIDL server\n which executes the driver lifecycle methods (e.g. Start, Stop).\n\n The secondary user of this is for bindings and tasks that require execution during\n suspend/resume lifecycle hooks. The driver host only calls these hooks when its safe\n to do so (dependent elements still exist).\n\n WARNING: Any other use will lead to execution while suspended, which may be unexpected."]
196    pub fn fdf_dispatcher_get_always_on_dispatcher(
197        dispatcher: *mut fdf_dispatcher_t,
198    ) -> *mut fdf_dispatcher_t;
199}
200unsafe extern "C" {
201    #[doc = " Registers a wake vector. Callbacks for |signals| received on this handle while suspended,\n wake the driver and execute after the driver's Resume hook, but before anything else.\n\n The handle wait does not need to be registered before this is called.\n This is a sticky registration; all future waits registered with this handle will\n automatically inherit this wakeability.\n\n Registration is cumulative; new signals are combined with any existing wake signals\n registered for this handle.\n\n |handle| is borrowed\n |dispatcher| is the dispatcher that the wake vector applies to.\n |signals| are the signals that will wake the driver\n\n # Errors\n\n ZX_ERR_BAD_STATE: The dispatcher is suspended."]
202    pub fn fdf_dispatcher_register_wake_vector(
203        dispatcher: *mut fdf_dispatcher_t,
204        handle: zx_handle_t,
205        signals: zx_signals_t,
206    ) -> zx_status_t;
207}
208unsafe extern "C" {
209    #[doc = " Unregisters the signals on the given handle as wake vectors.\n\n If the |signals| provided don't exactly match the signals that are currently\n registered, the delta between the two will still remain registered.\n\n |handle| is borrowed\n |dispatcher| is the dispatcher that the wake vector is removed from.\n |signals| are the signals that will be unregistered\n\n # Errors\n\n ZX_ERR_NOT_FOUND: The |handle| was never registered."]
210    pub fn fdf_dispatcher_unregister_wake_vector(
211        dispatcher: *mut fdf_dispatcher_t,
212        handle: zx_handle_t,
213        signals: zx_signals_t,
214    ) -> zx_status_t;
215}
216unsafe extern "C" {
217    #[doc = " Closes a handle, causing the underlying object to be reclaimed by the runtime\n if no other handles to it exist.\n\n If there is a pending callback registered (such as via |fdf_channel_wait_async|),\n it must be cancelled before this is called. For unsynchronized dispatchers,\n cancellation is not considered complete until the callback is invoked.\n\n It is not an error to close the special \"never a valid handle\" |FDF_HANDLE_INVALID|,\n similar to free(NULL) being a valid call.\n\n Closing the last handle to a peered object using |fdf_handle_close| can affect the\n state of the object's peer (if any).\n\n This operation is thread-safe."]
218    pub fn fdf_handle_close(handle: fdf_handle_t);
219}
220unsafe extern "C" {
221    #[doc = " Creates a FDF channel, a bi-directional in-process message transport capable of\n sending arena-managed raw data bytes as well as handles from one side to the other.\n\n Two handles are returned on success, providing access to both sides of the channel.\n Messages written to one handle may be read from the opposite.\n\n # Errors\n\n ZX_ERR_INVALID_ARGS: |out0| or |out1| is an invalid pointer or NULL or |options| is any value\n other than 0.\n\n ZX_ERR_NO_MEMORY: Failed due to a lack of memory.\n\n ZX_ERR_NO_RESOURCES: No handles are available."]
222    pub fn fdf_channel_create(
223        options: u32,
224        out0: *mut fdf_handle_t,
225        out1: *mut fdf_handle_t,
226    ) -> zx_status_t;
227}
228unsafe extern "C" {
229    #[doc = " Attempts to write a message to the channel specified by |channel|.\n\n The caller retains ownership of the |arena| reference, which must be destroyed via\n |fdf_arena_drop_ref|. It is okay to call |fdf_arena_drop_ref| on the arena as soon as\n the write call returns, as |fdf_arena_write| will take its own reference to the arena,\n extending the lifetime of the arena is until the data is read.\n\n The pointers |data| and |handles| may be NULL if their respective sizes are zero.\n |data| and |handles| must be pointers managed by |arena| if they are not NULL.\n |handles| may be a mix of zircon handles and fdf handles.\n\n Handles with a pending callback registered via |fdf_channel_wait_async| cannot be transferred.\n\n On success, all |num_handles| of the handles in the handles array are attached to the\n message and will become available to the reader of that message from the opposite end of the\n channel.\n\n All handles are consumed and are no longer available to the caller, on success or failure.\n\n # Errors\n\n ZX_ERR_INVALID_ARGS: |data| or |handles| are not pointers managed by |arena|,\n or any element in |handles| is not a valid handle,\n or at least one of |handles| has a pending callback registered via |fdf_channel_wait_async|.\n\n ZX_ERR_NO_MEMORY: Failed due to a lack of memory.\n\n ZX_ERR_PEER_CLOSED: The other side of the channel is closed.\n\n This operation is thread-safe."]
230    pub fn fdf_channel_write(
231        channel: fdf_handle_t,
232        options: u32,
233        arena: *mut fdf_arena_t,
234        data: *mut ::core::ffi::c_void,
235        num_bytes: u32,
236        handles: *mut zx_handle_t,
237        num_handles: u32,
238    ) -> zx_status_t;
239}
240unsafe extern "C" {
241    #[doc = " Attempts to read the first message from the channel specified by |channel| into\n the |data| and |handles| buffers.\n\n Provides ownership of the |arena| reference, which must be destroyed via |fdf_arena_drop_ref|.\n\n The lifetime of |data| and |handles| are tied to the lifetime of |arena|.\n |handles| may be a mix of zircon handles and fdf handles.\n\n The length of bytes, in bytes, is stored in the location pointed to by |out_num_bytes|.\n The number of handles is stored in the location pointed to by |out_num_handles|.\n Either |out_num_bytes| or |out_num_handles| may be NULL, in which case they will be ignored.\n\n # Errors\n\n ZX_ERR_INVALID_ARGS: |arena| is NULL when |data| or |handles| are non-NULL.\n\n ZX_ERR_SHOULD_WAIT: The channel contained no messages to read.\n\n ZX_ERR_PEER_CLOSED: There are no available messages and the other\n side of the channel is closed.\n\n This operation is thread-safe."]
242    pub fn fdf_channel_read(
243        channel: fdf_handle_t,
244        options: u32,
245        out_arena: *mut *mut fdf_arena_t,
246        out_data: *mut *mut ::core::ffi::c_void,
247        out_num_bytes: *mut u32,
248        out_handles: *mut *mut zx_handle_t,
249        out_num_handles: *mut u32,
250    ) -> zx_status_t;
251}
252unsafe extern "C" {
253    #[doc = " Begins asynchronously waiting for the channel set in |channel_read| to be readable.\n The |dispatcher| invokes the handler when the wait completes.\n Only one dispatcher can be registered at a time. The dispatcher will\n be considered unregistered immediately before the read handler is invoked.\n\n After successfully scheduling the read, the client is responsible for retaining\n the |channel_read| structure in memory (and unmodified) until the read handler runs,\n or the dispatcher shuts down.  Thereafter, the |channel_read| may be started again\n or destroyed.\n\n The read handler will be invoked exactly once. When the dispatcher is\n shutting down (being destroyed), the handlers of any remaining wait\n may be invoked with a status of |ZX_ERR_CANCELED|.\n\n If |FDF_CHANNEL_WAIT_OPTION_FORCE_ASYNC_CANCEL| is passed in |options|, a call\n to |fdf_channel_cancel_wait| will always call the callback rather than\n cancelling synchronously, even if the wait was started on a synchronized\n dispatcher.\n\n # Errors\n\n ZX_ERR_INVALID_ARGS: |dispatcher| or |channel_read| is an invalid pointer or NULL\n or |options| is an unknown option.\n\n ZX_ERR_PEER_CLOSED: There are no available messages and the other\n side of the channel is closed.\n\n ZX_ERR_BAD_STATE: There is already a dispatcher waiting on this channel.\n\n ZX_ERR_UNAVAILABLE: |dispatcher| is shutting down.\n\n This operation is thread-safe."]
254    pub fn fdf_channel_wait_async(
255        dispatcher: *mut fdf_dispatcher,
256        channel_read: *mut fdf_channel_read,
257        options: u32,
258    ) -> zx_status_t;
259}
260unsafe extern "C" {
261    #[doc = " Cancels any pending callback registered via |fdf_channel_wait_async|.\n\n Whether the wait handler will run depends on whether the dispatcher it was registered with is\n synchronized or |FDF_CHANNEL_WAIT_OPTION_FORCE_ASYNC_CANCEL| was passed with in\n |fdf_channel_wait_async|.\n\n If the dispatcher is synchronized and |FDF_CHANNEL_WAIT_OPTION_FORCE_ASYNC_CANCEL| was not\n passed, this must only be called from a dispatcher thread, and any pending callback will be\n canceled synchronously.\n\n If the dispatcher is unsynchronized or |FDF_CHANNEL_WAIT_OPTION_FORCE_ASYNC_CANCEL| was passed,\n the callback will be scheduled to be called with status |ZX_ERR_CANCELED|.\n\n # Errors\n\n ZX_ERR_NOT_FOUND: There was no pending wait either because it is currently running (perhaps in a\n different thread), already scheduled to be run, already completed, or had not been started."]
262    pub fn fdf_channel_cancel_wait(handle: fdf_handle_t) -> zx_status_t;
263}
264unsafe extern "C" {
265    #[doc = " fdf_channel_call() is like a combined fdf_channel_write(), fdf_channel_wait_async(),\n and fdf_channel_read(), with the addition of a feature where a transaction id at\n the front of the message payload bytes is used to match reply messages with send messages,\n enabling multiple calling threads to share a channel without any additional client-side\n bookkeeping.\n\n The first four bytes of the written and read back messages are treated as a\n transaction ID of type fdf_txid_t. The runtime generates a txid for the\n written message, replacing that part of the message as read from the user.\n The runtime generated txid will be between 0x80000000 and 0xFFFFFFFF,\n and will not collide with any txid from any other fdf_channel_call()\n in progress against this channel endpoint. If the written message has a\n length of fewer than four bytes, an error is reported.\n\n While |deadline| has not passed, if an inbound message arrives with a matching txid,\n instead of being added to the tail of the general inbound message queue,\n it is delivered directly to the thread waiting in fdf_channel_call().\n\n If such a reply arrives after |deadline| has passed, it will arrive in the\n general inbound message queue.\n\n All written handles are consumed and are no longer available to the caller,\n on success or failure.\n\n # Errors\n\n ZX_ERR_INVALID_ARGS: |args| is NULL,\n or |wr_data| or |wr_handles| are non-NULL and not pointers managed by |wr_arena|,\n or any element in |handles| is not a valid handle,\n or |wr_num_bytes| is less than four,\n or at least one of |wr_handles| has a pending callback registered via |fdf_channel_wait_async|,\n or |rd_arena| is NULL when |rd_data| or |rd_handles| are non-NULL.\n\n ZX_ERR_PEER_CLOSED: The other side of the channel is closed.\n\n ZX_ERR_TIMED_OUT: |deadline| passed before a reply matching\n the correct txid was received.\n\n ZX_ERR_BAD_STATE: This is called from a driver runtime managed thread\n that does not allow sync calls.\n\n This operation is thread-safe."]
266    pub fn fdf_channel_call(
267        handle: fdf_handle_t,
268        options: u32,
269        deadline: zx_time_t,
270        args: *const fdf_channel_call_args_t,
271    ) -> zx_status_t;
272}
273#[doc = " A bi-directional in-process message transport capable of sending arena-managed raw data bytes\n as well as handles from one side to the other.\n\n # Thread safety\n\n Most operations on channel objects are thread-safe, except for |fdf_channel_cancel_wait|.\n\n # Example\n\n   // Read handler for asynchronous channel reads.\n   void read_handler(fdf_dispatcher_t* dispatcher, fdf_channel_read_t* read, zx_status_t status);\n\n   // Sends a request to the peer of |channel| and asynchronously waits for a response.\n   void send_request(fdf_handle_t channel, fdf_dispatcher_t* dispatcher dispatcher) {\n     fdf_arena_t* arena;\n     zx_status_t status = fdf_arena_create(0, 'exam', 0, &arena);\n\n     void* data = fdf_arena_allocate(arena, 0x1000);\n     // Set the data to transfer\n     ...\n\n     // Write the request to the channel.\n     status = fdf_channel_write(ch0, 0, arena, data, 0x1000, NULL, 0);\n\n     // Asynchronously wait for a response.\n     fdf_channel_read_t* channel_read = calloc(1, sizeof(fdf_channel_read_t));\n     channel_read->handler = read_handler;\n     channel_read->channel = ch0;\n     status = fdf_channel_wait_async(dispatcher, channel_read, 0);\n\n     // We are done with the arena.\n     fdf_arena_drop_ref(arena);\n   }\n\n   void read_handler(fdf_dispatcher_t* dispatcher, fdf_channel_read_t* read,\n                     zx_status_t status) {\n     fdf_arena_t* arena;\n     void* data data;\n     uint32_t data_size;\n     zx_handle_t* handles;\n     uint32_t num_handles;\n     zx_status_t status = fdf_channel_read(read->channel, 0, &arena, &data, &data_size,\n                                            &handles, &num_handles);\n     // Process the read data.\n     ...\n\n     // Read provides you with an arena which you may reuse for other requests.\n     // You are in charge of destroying the reference.\n     fdf_arena_drop_ref(arena);\n     free(read);\n   }\n"]
274pub type fdf_channel_read_t = fdf_channel_read;
275#[doc = " Handles execution of asynchronous read operations.\n\n The |status| is |ZX_OK| if the channel is ready to be read.\n The |status| is |ZX_ERR_CANCELED| if the dispatcher was shut down before\n the read handler ran."]
276pub type fdf_channel_read_handler_t = ::core::option::Option<
277    unsafe extern "C" fn(
278        dispatcher: *mut fdf_dispatcher_t,
279        read: *mut fdf_channel_read_t,
280        status: zx_status_t,
281    ),
282>;
283#[doc = " A bi-directional in-process message transport capable of sending arena-managed raw data bytes\n as well as handles from one side to the other.\n\n # Thread safety\n\n Most operations on channel objects are thread-safe, except for |fdf_channel_cancel_wait|.\n\n # Example\n\n   // Read handler for asynchronous channel reads.\n   void read_handler(fdf_dispatcher_t* dispatcher, fdf_channel_read_t* read, zx_status_t status);\n\n   // Sends a request to the peer of |channel| and asynchronously waits for a response.\n   void send_request(fdf_handle_t channel, fdf_dispatcher_t* dispatcher dispatcher) {\n     fdf_arena_t* arena;\n     zx_status_t status = fdf_arena_create(0, 'exam', 0, &arena);\n\n     void* data = fdf_arena_allocate(arena, 0x1000);\n     // Set the data to transfer\n     ...\n\n     // Write the request to the channel.\n     status = fdf_channel_write(ch0, 0, arena, data, 0x1000, NULL, 0);\n\n     // Asynchronously wait for a response.\n     fdf_channel_read_t* channel_read = calloc(1, sizeof(fdf_channel_read_t));\n     channel_read->handler = read_handler;\n     channel_read->channel = ch0;\n     status = fdf_channel_wait_async(dispatcher, channel_read, 0);\n\n     // We are done with the arena.\n     fdf_arena_drop_ref(arena);\n   }\n\n   void read_handler(fdf_dispatcher_t* dispatcher, fdf_channel_read_t* read,\n                     zx_status_t status) {\n     fdf_arena_t* arena;\n     void* data data;\n     uint32_t data_size;\n     zx_handle_t* handles;\n     uint32_t num_handles;\n     zx_status_t status = fdf_channel_read(read->channel, 0, &arena, &data, &data_size,\n                                            &handles, &num_handles);\n     // Process the read data.\n     ...\n\n     // Read provides you with an arena which you may reuse for other requests.\n     // You are in charge of destroying the reference.\n     fdf_arena_drop_ref(arena);\n     free(read);\n   }\n"]
284#[repr(C)]
285pub struct fdf_channel_read {
286    pub state: async_state_t,
287    pub handler: fdf_channel_read_handler_t,
288    pub channel: fdf_handle_t,
289    pub options: u32,
290}
291#[allow(clippy::unnecessary_operation, clippy::identity_op)]
292const _: () = {
293    ["Size of fdf_channel_read"][::core::mem::size_of::<fdf_channel_read>() - 32usize];
294    ["Alignment of fdf_channel_read"][::core::mem::align_of::<fdf_channel_read>() - 8usize];
295    ["Offset of field: fdf_channel_read::state"]
296        [::core::mem::offset_of!(fdf_channel_read, state) - 0usize];
297    ["Offset of field: fdf_channel_read::handler"]
298        [::core::mem::offset_of!(fdf_channel_read, handler) - 16usize];
299    ["Offset of field: fdf_channel_read::channel"]
300        [::core::mem::offset_of!(fdf_channel_read, channel) - 24usize];
301    ["Offset of field: fdf_channel_read::options"]
302        [::core::mem::offset_of!(fdf_channel_read, options) - 28usize];
303};
304impl Default for fdf_channel_read {
305    fn default() -> Self {
306        let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
307        unsafe {
308            ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
309            s.assume_init()
310        }
311    }
312}
313impl ::core::fmt::Debug for fdf_channel_read {
314    fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
315        write!(f, "fdf_channel_read {{ handler: {:?} }}", self.handler)
316    }
317}
318#[doc = " Holds context for the observer which will be called when the asynchronous shutdown\n for all dispatchers owned by a driver has completed.\n\n The client is responsible for retaining this structure in memory (and unmodified) until the\n handler runs."]
319pub type fdf_env_driver_shutdown_observer_t = fdf_env_driver_shutdown_observer;
320#[doc = " Called when the asynchronous shutdown for all dispatchers owned by |driver| has completed."]
321pub type fdf_env_driver_shutdown_handler_t = ::core::option::Option<
322    unsafe extern "C" fn(
323        driver: *const ::core::ffi::c_void,
324        observer: *mut fdf_env_driver_shutdown_observer_t,
325    ),
326>;
327#[doc = " Holds context for the observer which will be called when the asynchronous shutdown\n for all dispatchers owned by a driver has completed.\n\n The client is responsible for retaining this structure in memory (and unmodified) until the\n handler runs."]
328#[repr(C)]
329#[derive(Debug, Default, Copy, Clone)]
330pub struct fdf_env_driver_shutdown_observer {
331    pub handler: fdf_env_driver_shutdown_handler_t,
332}
333#[allow(clippy::unnecessary_operation, clippy::identity_op)]
334const _: () = {
335    ["Size of fdf_env_driver_shutdown_observer"]
336        [::core::mem::size_of::<fdf_env_driver_shutdown_observer>() - 8usize];
337    ["Alignment of fdf_env_driver_shutdown_observer"]
338        [::core::mem::align_of::<fdf_env_driver_shutdown_observer>() - 8usize];
339    ["Offset of field: fdf_env_driver_shutdown_observer::handler"]
340        [::core::mem::offset_of!(fdf_env_driver_shutdown_observer, handler) - 0usize];
341};
342#[doc = " Holds context for the stall scanner which will be called when stall scanning should occur.\n\n The client is responsible for retaining this structure in memory (and unmodified) until the\n handler runs."]
343pub type fdf_env_stall_scanner_t = fdf_env_stall_scanner;
344#[doc = " Called when stall scanning should begin."]
345pub type fdf_env_stall_scan_begin = ::core::option::Option<
346    unsafe extern "C" fn(scanner: *mut fdf_env_stall_scanner_t, duration: zx_duration_mono_t),
347>;
348#[doc = " Holds context for the stall scanner which will be called when stall scanning should occur.\n\n The client is responsible for retaining this structure in memory (and unmodified) until the\n handler runs."]
349#[repr(C)]
350#[derive(Debug, Default, Copy, Clone)]
351pub struct fdf_env_stall_scanner {
352    pub handler: fdf_env_stall_scan_begin,
353}
354#[allow(clippy::unnecessary_operation, clippy::identity_op)]
355const _: () = {
356    ["Size of fdf_env_stall_scanner"][::core::mem::size_of::<fdf_env_stall_scanner>() - 8usize];
357    ["Alignment of fdf_env_stall_scanner"]
358        [::core::mem::align_of::<fdf_env_stall_scanner>() - 8usize];
359    ["Offset of field: fdf_env_stall_scanner::handler"]
360        [::core::mem::offset_of!(fdf_env_stall_scanner, handler) - 0usize];
361};
362#[doc = " Holds context for the resume request which will be called when the runtime needs to be\n resumed.\n\n The client is responsible for retaining this structure in memory (and unmodified) until the\n handler runs."]
363pub type fdf_env_resume_requester_t = fdf_env_resume_requester;
364#[doc = " Called by the runtime to request to be resumed."]
365pub type fdf_env_resume_request = ::core::option::Option<
366    unsafe extern "C" fn(requester: *mut fdf_env_resume_requester_t) -> zx_status_t,
367>;
368#[doc = " Holds context for the resume request which will be called when the runtime needs to be\n resumed.\n\n The client is responsible for retaining this structure in memory (and unmodified) until the\n handler runs."]
369#[repr(C)]
370#[derive(Debug, Default, Copy, Clone)]
371pub struct fdf_env_resume_requester {
372    pub handler: fdf_env_resume_request,
373}
374#[allow(clippy::unnecessary_operation, clippy::identity_op)]
375const _: () = {
376    ["Size of fdf_env_resume_requester"]
377        [::core::mem::size_of::<fdf_env_resume_requester>() - 8usize];
378    ["Alignment of fdf_env_resume_requester"]
379        [::core::mem::align_of::<fdf_env_resume_requester>() - 8usize];
380    ["Offset of field: fdf_env_resume_requester::handler"]
381        [::core::mem::offset_of!(fdf_env_resume_requester, handler) - 0usize];
382};
383#[doc = " Holds context for the suspend completion which will be called when the driver\n has completed suspending.\n\n The client is responsible for retaining this structure in memory (and unmodified) until the\n handler runs."]
384pub type fdf_env_suspend_completer_t = fdf_env_suspend_completer;
385#[doc = " Called by the runtime to signal completion of suspend."]
386pub type fdf_env_suspend_complete =
387    ::core::option::Option<unsafe extern "C" fn(completer: *mut fdf_env_suspend_completer_t)>;
388#[doc = " Holds context for the suspend completion which will be called when the driver\n has completed suspending.\n\n The client is responsible for retaining this structure in memory (and unmodified) until the\n handler runs."]
389#[repr(C)]
390#[derive(Debug, Default, Copy, Clone)]
391pub struct fdf_env_suspend_completer {
392    pub handler: fdf_env_suspend_complete,
393}
394#[allow(clippy::unnecessary_operation, clippy::identity_op)]
395const _: () = {
396    ["Size of fdf_env_suspend_completer"]
397        [::core::mem::size_of::<fdf_env_suspend_completer>() - 8usize];
398    ["Alignment of fdf_env_suspend_completer"]
399        [::core::mem::align_of::<fdf_env_suspend_completer>() - 8usize];
400    ["Offset of field: fdf_env_suspend_completer::handler"]
401        [::core::mem::offset_of!(fdf_env_suspend_completer, handler) - 0usize];
402};
403unsafe extern "C" {
404    #[doc = " Start the driver runtime. This sets up the initial thread that the dispatchers run on."]
405    pub fn fdf_env_start(options: u32) -> zx_status_t;
406}
407unsafe extern "C" {
408    #[doc = " Resets the driver runtime to zero threads. This may only be called when there are no\n existing dispatchers."]
409    pub fn fdf_env_reset();
410}
411unsafe extern "C" {
412    #[doc = " Same as |fdf_dispatcher_create| but allows setting the driver owner for the dispatcher.\n\n |driver| is an opaque pointer to the driver object. It will be used to uniquely identify\n the driver."]
413    pub fn fdf_env_dispatcher_create_with_owner(
414        driver: *const ::core::ffi::c_void,
415        options: u32,
416        name: *const ::core::ffi::c_char,
417        name_len: usize,
418        scheduler_role: *const ::core::ffi::c_char,
419        scheduler_role_len: usize,
420        observer: *mut fdf_dispatcher_shutdown_observer_t,
421        out_dispatcher: *mut *mut fdf_dispatcher_t,
422    ) -> zx_status_t;
423}
424unsafe extern "C" {
425    #[doc = " Dumps the state of the dispatcher to the INFO log."]
426    pub fn fdf_env_dispatcher_dump(dispatcher: *mut fdf_dispatcher_t);
427}
428unsafe extern "C" {
429    #[doc = " DO NOT USE THIS.\n This is a temporary function added to debug https://fxbug.dev/42069837.\n\n Dumps the state of the dispatcher into |out_dump|, as a NULL terminated string.\n The caller is responsible for freeing |out_dump|."]
430    pub fn fdf_env_dispatcher_get_dump_deprecated(
431        dispatcher: *mut fdf_dispatcher_t,
432        out_dump: *mut *mut ::core::ffi::c_char,
433    );
434}
435unsafe extern "C" {
436    #[doc = " Asynchronously shuts down all dispatchers owned by |driver|.\n |observer| will be notified once shutdown completes. This is guaranteed to be\n after all the dispatcher's shutdown observers have been called, and will be running\n on the thread of the final dispatcher which has been shutdown.\n\n While a driver is shutting down, no new dispatchers can be created by the driver.\n\n If this succeeds, you must keep the |observer| object alive until the\n |observer| is notified.\n\n # Errors\n\n ZX_ERR_INVALID_ARGS: No driver matching |driver| was found.\n\n ZX_ERR_BAD_STATE: A driver shutdown observer was already registered."]
437    pub fn fdf_env_shutdown_dispatchers_async(
438        driver: *const ::core::ffi::c_void,
439        observer: *mut fdf_env_driver_shutdown_observer_t,
440    ) -> zx_status_t;
441}
442unsafe extern "C" {
443    #[doc = " Destroys all dispatchers in the process and blocks the current thread\n until each runtime dispatcher in the process is observed to have been destroyed.\n\n This should only be used called after all dispatchers have been shutdown.\n\n # Thread requirements\n\n This should not be called from a thread managed by the driver runtime,\n such as from tasks or ChannelRead callbacks."]
444    pub fn fdf_env_destroy_all_dispatchers();
445}
446unsafe extern "C" {
447    #[doc = " Notifies the runtime that we have entered a new driver context,\n such as via a Banjo call.\n\n |driver| is an opaque unique identifier for the driver."]
448    pub fn fdf_env_register_driver_entry(driver: *const ::core::ffi::c_void);
449}
450unsafe extern "C" {
451    #[doc = " Notifies the runtime that we have exited the current driver context."]
452    pub fn fdf_env_register_driver_exit();
453}
454unsafe extern "C" {
455    #[doc = " Returns the driver on top of the the thread's current call stack.\n Returns NULL if no drivers are on the stack."]
456    pub fn fdf_env_get_current_driver() -> *const ::core::ffi::c_void;
457}
458unsafe extern "C" {
459    #[doc = " Returns whether the dispatcher has any queued tasks."]
460    pub fn fdf_env_dispatcher_has_queued_tasks(dispatcher: *mut fdf_dispatcher_t) -> bool;
461}
462unsafe extern "C" {
463    #[doc = " Returns the current maximum number of threads which will be spawned for thread pool associated\n with the given scheduler role.\n\n |scheduler_role| is the name of the role which is passed when creating dispatchers.\n |scheduler_role_len | is the length of the string, without including the terminating\n NULL character."]
464    pub fn fdf_env_get_thread_limit(
465        scheduler_role: *const ::core::ffi::c_char,
466        scheduler_role_len: usize,
467    ) -> u32;
468}
469unsafe extern "C" {
470    #[doc = " Sets the number of threads which will be spawned for thread pool associated with the given\n scheduler role. It cannot shrink the limit less to a value lower than the current number of\n threads in the thread pool.\n\n |scheduler_role| is the name of the role which is passed when creating dispatchers.\n |scheduler_role_len | is the length of the string, without including the terminating\n NULL character.\n |max_threads| is the number of threads to use as new limit.\n\n # Errors\n\n ZX_ERR_OUT_OF_RANGE: |max_threads| is less that the current number of threads."]
471    pub fn fdf_env_set_thread_limit(
472        scheduler_role: *const ::core::ffi::c_char,
473        scheduler_role_len: usize,
474        max_threads: u32,
475    ) -> zx_status_t;
476}
477unsafe extern "C" {
478    #[doc = " Returns the currently set options for the scheduler role as a uint32_t bitmask.\n\n |scheduler_role| is the name of the role which is passed when creating dispatchers.\n |scheduler_role_len| is the length of the string, without including the terminating\n NULL character."]
479    pub fn fdf_env_get_scheduler_role_opts(
480        scheduler_role: *const ::core::ffi::c_char,
481        scheduler_role_len: usize,
482    ) -> u32;
483}
484unsafe extern "C" {
485    #[doc = " Sets the options for the given scheduler role. This can be used to enforce restrictions\n on the kinds of dispatchers that can be created on this scheduler role.\n\n Currently available options include:\n - `FDF_SCHEDULER_ROLE_OPTION_NO_SYNC_CALLS` will not allow any dispatchers on the\n scheduler role to be created with `FDF_DISPATCHER_OPTION_ALLOW_SYNC_CALLS`.\n\n |scheduler_role| is the name of the role which is passed when creating dispatchers.\n |scheduler_role_len| is the length of the string, without including the terminating\n NULL character.\n |options| is the new options for the scheduler role.\n\n # Errors\n\n ZX_ERR_INVALID_ARGS: |options| contains unknown or invalid options.\n ZX_ERR_NOT_SUPPORTED: |options| contains an option that wouldn't allow a dispatcher that\n already exists on this scheduler role."]
486    pub fn fdf_env_set_scheduler_role_opts(
487        scheduler_role: *const ::core::ffi::c_char,
488        scheduler_role_len: usize,
489        options: u32,
490    ) -> zx_status_t;
491}
492unsafe extern "C" {
493    #[doc = " Adds an allowed scheduler role for the given driver."]
494    pub fn fdf_env_add_allowed_scheduler_role_for_driver(
495        driver: *const ::core::ffi::c_void,
496        role: *const ::core::ffi::c_char,
497        role_length: usize,
498    );
499}
500unsafe extern "C" {
501    #[doc = " Gets the opaque pointer uniquely associated with the driver currently running on the\n thread identified by |tid|.\n\n Returns the driver pointer through out parameter |out_driver|.\n\n # Errors\n\n ZX_ERR_NOT_FOUND: If the tid did not have a driver running on it, or the tid was not able\n to be identified.\n\n ZX_ERR_INVALID_ARGS: If the out_driver is not valid."]
502    pub fn fdf_env_get_driver_on_tid(
503        tid: zx_koid_t,
504        out_driver: *mut *const ::core::ffi::c_void,
505    ) -> zx_status_t;
506}
507unsafe extern "C" {
508    #[doc = " Scans active thread pools for threads that are stalled on long running tasks and potentially\n spawn new threads to compensate.\n\n # Thread requirements\n\n This should not be called from a thread managed by the driver runtime, such as from tasks or\n ChannelRead callbacks."]
509    pub fn fdf_env_scan_threads_for_stalls();
510}
511unsafe extern "C" {
512    #[doc = " Scans active thread pools for threads that are stalled on long running tasks and potentially\n spawn new threads to compensate.\n\n Returns the amount of time the caller should wait before calling this again as a\n `zx_duration_mono_t`. If 0 is returned, scanning should suspend until a start callback is made\n via the registered stall scanner.\n\n # Thread requirements\n\n This should not be called from a thread managed by the driver runtime, such as from tasks or\n ChannelRead callbacks."]
513    pub fn fdf_env_scan_threads_for_stalls2() -> zx_duration_mono_t;
514}
515unsafe extern "C" {
516    #[doc = " Registers a for callbacks for when stall scanning should occur."]
517    pub fn fdf_env_register_stall_scanner(scanner: *mut fdf_env_stall_scanner_t);
518}
519unsafe extern "C" {
520    #[doc = " Registers for callbacks for when the driver needs to be resumed.\n The callback being triggered should eventually result in |fdf_env_driver_resume| being called."]
521    pub fn fdf_env_register_resume_requester(
522        driver: *const ::core::ffi::c_void,
523        requester: *mut fdf_env_resume_requester_t,
524    );
525}
526unsafe extern "C" {
527    #[doc = " Asynchronously suspends the dispatchers owned by the driver.\n The runtime will stop accepting new work and drain existing work before calling the completer."]
528    pub fn fdf_env_driver_suspend(
529        driver: *const ::core::ffi::c_void,
530        completer: *mut fdf_env_suspend_completer_t,
531    );
532}
533unsafe extern "C" {
534    #[doc = " Resumes the dispatchers owned by the driver.\n The runtime will move pending callbacks back to the main queue and start accepting new work."]
535    pub fn fdf_env_driver_resume(driver: *const ::core::ffi::c_void);
536}
537unsafe extern "C" {
538    #[doc = " Creates a dispatcher on a unmanaged thread pool. This means that there are no background threads\n handling this dispatcher and so it has to be ran explicitly using the various run calls.\n See |fdf_env_dispatcher_create_with_owner| for more information about the parameters and return\n value."]
539    pub fn fdf_testing_create_unmanaged_dispatcher(
540        driver: *const ::core::ffi::c_void,
541        options: u32,
542        name: *const ::core::ffi::c_char,
543        name_len: usize,
544        observer: *mut fdf_dispatcher_shutdown_observer_t,
545        out_dispatcher: *mut *mut fdf_dispatcher_t,
546    ) -> zx_status_t;
547}
548unsafe extern "C" {
549    #[doc = " Sets the default driver dispatcher to be returned when the current thread does not have a driver\n associated with it. This is useful for tests that want to attach a dispatcher to their main\n test thread, so that they can use objects that contains a synchronization_checker.\n |dispatcher| should have been created using |fdf_testing_create_unmanaged_dispatcher|, or be a\n nullptr to remove an existing default.\n\n Returns |ZX_OK| if set successfully.\n Returns |ZX_ERR_BAD_STATE| if called from a thread managed by the driver runtime."]
550    pub fn fdf_testing_set_default_dispatcher(dispatcher: *mut fdf_dispatcher_t) -> zx_status_t;
551}
552unsafe extern "C" {
553    #[doc = " Runs the unmanaged dispatcher pool on the current thread.\n\n Dispatches events until the |deadline| expires or it is quit.\n Use |ZX_TIME_INFINITE| to dispatch events indefinitely.\n\n If |once| is true, performs a single unit of work then returns.\n\n Returns |ZX_OK| if the dispatcher returns after one cycle.\n Returns |ZX_ERR_TIMED_OUT| if the deadline expired.\n Returns |ZX_ERR_CANCELED| if it quit.\n Returns |ZX_ERR_BAD_STATE| if the unmanaged dispatcher was shut down or if an unmanaged\n dispatcher has not been created."]
554    pub fn fdf_testing_run(deadline: zx_time_t, once: bool) -> zx_status_t;
555}
556unsafe extern "C" {
557    #[doc = " Runs the unmanaged dispatcher pool on the current thread. Dispatches events until there are none\n remaining, and then returns without waiting. This is useful for unit testing, because the\n behavior doesn't depend on time.\n\n Returns |ZX_OK| if the dispatcher reaches an idle state.\n Returns |ZX_ERR_CANCELED| if it is quit.\n Returns |ZX_ERR_BAD_STATE| if the unmanaged dispatcher was shut down or if an unmanaged\n dispatcher has not been created."]
558    pub fn fdf_testing_run_until_idle() -> zx_status_t;
559}
560unsafe extern "C" {
561    #[doc = " Quits the unmanaged dispatcher pool if one has been created. Otherwise does nothing.\n Active invocations of |fdf_testing_run()| will eventually terminate upon completion of their\n current unit of work.\n\n Subsequent calls to |fdf_testing_run()|\n will return immediately until |fdf_testing_reset_quit()| is called."]
562    pub fn fdf_testing_quit();
563}
564unsafe extern "C" {
565    #[doc = " Resets the quit state of the unmanaged dispatcher pool so that it can be restarted\n using |fdf_testing_run()|.\n\n This function must only be called when the unmanaged dispatcher pool is not running.\n The caller must ensure all active invocations of |fdf_testing_run()| have terminated before\n resetting the quit state.\n\n Returns |ZX_OK| if the unmanaged dispatcher pool's quit state was correctly reset.\n Returns |ZX_ERR_BAD_STATE| if the unmanaged dispatcher pool was shutting down or if\n it was currently actively running, or if an unmanaged dispatcher has not been created."]
566    pub fn fdf_testing_reset_quit() -> zx_status_t;
567}
568#[doc = " Tokens provide a mechanism for transferring FDF handles between drivers in the same process\n when a driver FIDL transport is not available. This is necessary as FDF handles cannot be\n transferred using the Zircon channel FIDL transport.\n\n A token is represented as a Zircon channel pair.\n\n # Example\n\n   // Child driver\n\n   void my_function() {\n     zx_channel_t token_local, token_remote;\n     zx_status_t status = zx_channel_create(0, &token_local, &token_remote);\n     ...\n     // Transfer |token_remote| to parent driver, perhaps over FIDL.\n     ...\n     fdf_handle_t channel_local, channel_remote;\n     status = fdf_channel_create(0, &channel_local, &channel_remote);\n     ...\n     zx_status_t status = fdf_token_transfer(token_local, channel_remote);\n     // The FDF handle |channel_remote| can be received by the parent\n     // driver who has the other side of the token.\n   }\n\n   // Parent driver\n\n   void my_function() {\n     zx_handle_t token;\n     // Token received from child driver.\n     ...\n     // Receive the driver handle for the token\n     fdf_handle_t channel;\n     zx_status_t status = fdf_token_receive(token, &channel);\n     ...\n   }"]
569pub type fdf_token_t = fdf_token;
570#[doc = " Handles the transfer of the fdf handle.\n\n If |status| is ZX_OK, transfers ownership of |handle|.\n\n The status is |ZX_OK| if the token was successfully transferred.\n The status is |ZX_ERR_CANCELED| if the dispatcher was shut down before the\n transfer was completed, or the peer token handle has been closed."]
571pub type fdf_token_transfer_handler_t = ::core::option::Option<
572    unsafe extern "C" fn(
573        dispatcher: *mut fdf_dispatcher_t,
574        token: *mut fdf_token_t,
575        status: zx_status_t,
576        handle: fdf_handle_t,
577    ),
578>;
579#[doc = " Holds context for a registered token which is waiting for an fdf handle to be transferred.\n\n After successfully registering the protocol, the client is responsible for retaining\n the structure in memory (and unmodified) until the transfer handler runs.\n Thereafter, this structure may be registered again or destroyed."]
580#[repr(C)]
581#[derive(Debug, Default, Copy, Clone)]
582pub struct fdf_token {
583    pub handler: fdf_token_transfer_handler_t,
584}
585#[allow(clippy::unnecessary_operation, clippy::identity_op)]
586const _: () = {
587    ["Size of fdf_token"][::core::mem::size_of::<fdf_token>() - 8usize];
588    ["Alignment of fdf_token"][::core::mem::align_of::<fdf_token>() - 8usize];
589    ["Offset of field: fdf_token::handler"][::core::mem::offset_of!(fdf_token, handler) - 0usize];
590};
591unsafe extern "C" {
592    #[doc = " Registers a token transfer handler for |token|.\n\n Note: This function is deprecated and will be removed at a later date. You should use\n |fdf_token_receive| instead.\n\n The transfer handler will be scheduled to be called on the dispatcher when a client calls\n |fdf_token_transfer| with the channel peer of |token|, If the connection has already been\n requested, the handler will be scheduled immediately.\n\n Transfers ownership of |token| to the runtime.\n\n All handles are consumed and are no longer available to the caller, on success or failure.\n\n # Errors\n\n ZX_ERR_BAD_HANDLE: |token| is not a valid channel handle.\n\n ZX_ERR_INVALID_ARGS: |handler| or |dispatcher| is NULL.\n\n ZX_ERR_BAD_STATE: The dispatcher is shutting down, or |handler|\n has already been registered."]
593    pub fn fdf_token_register(
594        token: zx_handle_t,
595        dispatcher: *mut fdf_dispatcher_t,
596        handler: *mut fdf_token_t,
597    ) -> zx_status_t;
598}
599unsafe extern "C" {
600    #[doc = " Receives the corresponding driver handle for |token| if it has been transferred.\n\n If |fdf_token_transfer| has been called on |token|'s pair, this will receive the\n driver handle that was passed to it and store it in the address pointed to by\n |handle|.\n\n Transfers ownership of |token| to the runtime.\n\n The |token| handle is consumed and is no longer available to the caller, on success or failure.\n\n # Errors\n\n ZX_ERR_BAD_HANDLE: |token| is not a valid channel handle.\n\n ZX_ERR_INVALID_ARGS: |handle| is NULL.\n\n ZX_ERR_NOT_FOUND: The |token|'s pair has not been transferred before this\n call."]
601    pub fn fdf_token_receive(token: zx_handle_t, handle: *mut fdf_handle_t) -> zx_status_t;
602}
603unsafe extern "C" {
604    #[doc = " Transfers the fdf handle to the owner of the channel peer of |token|.\n\n The token transfer handler which was, or will be registered with the\n channel peer of |token| will receive |handle|.\n\n Transfers ownership of |token| to the runtime, and ownership of |handle| to\n the driver who registered the token.\n\n All handles are consumed and are no longer available to the caller, on success or failure.\n\n # Errors\n\n ZX_ERR_BAD_HANDLE: |token| is not a valid channel handle,\n or |handle| is not a valid FDF handle.\n\n ZX_ERR_BAD_STATE: The dispatcher is shutting down."]
605    pub fn fdf_token_transfer(token: zx_handle_t, handle: fdf_handle_t) -> zx_status_t;
606}
607#[doc = " The |DriverRegistration| is the ABI for drivers to expose themselves to the Driver Framework.\n The driver is loaded in as a shared library (also referred to as a DSO), and the global symbol\n `__fuchsia_driver_registration__` is used by the Driver Framework to locate this\n DriverRegistration in the driver library. The framework will use this to initiate a FIDL based\n connection over the driver transport into the driver."]
608#[repr(C)]
609#[derive(Debug, Default, Copy, Clone)]
610pub struct DriverRegistration {
611    #[doc = " The version is not expected to change since the evolution of the driver APIs will happen\n on the FIDL side. This simply exists in case we need to evolve the initialization signature\n for any reason."]
612    pub version: u64,
613    pub v1: DriverRegistration_driver_registration_v1,
614}
615#[repr(C)]
616#[derive(Debug, Default, Copy, Clone)]
617pub struct DriverRegistration_driver_registration_v1 {
618    #[doc = " Pointer to a function that can initialize the driver server on the |server_handle|.\n\n Errors to initialize the driver server can be propagated by closing the |server_handle| with\n an epitaph, but driver start failures should use the corresponding FIDL protocol.\n\n This function is executed on the default driver dispatcher. This dispatcher is synchronized\n and runs on a shared driver thread within a `driver_host`. The driver can access this\n dispatcher using |fdf_dispatcher_get_current_dispatcher()| or in C++ with\n |fdf::Dispatcher::GetCurrent()|. This can be stored in an\n |fdf::UnownedSynchronizedDispatcher| as the driver host is the owner of the dispatcher.\n\n |server_handle| is the server end for the |fuchsia.driver.framework/Driver| protocol that\n the driver should begin serving on. This should be served on the driver dispatcher\n that this function is executed on.\n\n The return result is a `void*` token that the driver framework will pass into |destroy|."]
619    pub initialize: ::core::option::Option<
620        unsafe extern "C" fn(server_handle: fdf_handle_t) -> *mut ::core::ffi::c_void,
621    >,
622    #[doc = " Pointer to a function that can free the resources that were allocated as part of\n |initialize|. Generally this will just be the object allocated to serve the\n |fuchsia.driver.framework/Driver| protocol.\n\n This function is executed after all of the dispatchers belonging to the driver have fully\n been shutdown, including the default dispatcher that |initialize| was executed on.\n\n |token| is the return result of the |initialize| function."]
623    pub destroy: ::core::option::Option<unsafe extern "C" fn(token: *mut ::core::ffi::c_void)>,
624}
625#[allow(clippy::unnecessary_operation, clippy::identity_op)]
626const _: () = {
627    ["Size of DriverRegistration_driver_registration_v1"]
628        [::core::mem::size_of::<DriverRegistration_driver_registration_v1>() - 16usize];
629    ["Alignment of DriverRegistration_driver_registration_v1"]
630        [::core::mem::align_of::<DriverRegistration_driver_registration_v1>() - 8usize];
631    ["Offset of field: DriverRegistration_driver_registration_v1::initialize"]
632        [::core::mem::offset_of!(DriverRegistration_driver_registration_v1, initialize) - 0usize];
633    ["Offset of field: DriverRegistration_driver_registration_v1::destroy"]
634        [::core::mem::offset_of!(DriverRegistration_driver_registration_v1, destroy) - 8usize];
635};
636#[allow(clippy::unnecessary_operation, clippy::identity_op)]
637const _: () = {
638    ["Size of DriverRegistration"][::core::mem::size_of::<DriverRegistration>() - 24usize];
639    ["Alignment of DriverRegistration"][::core::mem::align_of::<DriverRegistration>() - 8usize];
640    ["Offset of field: DriverRegistration::version"]
641        [::core::mem::offset_of!(DriverRegistration, version) - 0usize];
642    ["Offset of field: DriverRegistration::v1"]
643        [::core::mem::offset_of!(DriverRegistration, v1) - 8usize];
644};
645pub const DRIVER_REGISTRATION_VERSION_1: u64 = 1;
646pub const DRIVER_REGISTRATION_VERSION_MAX: u64 = 1;