Skip to main content

dispatch2/generated/
mod.rs

1// This file has been automatically generated by `objc2`'s `header-translator`.
2// DO NOT EDIT
3
4#![allow(unused_imports)]
5#![allow(deprecated)]
6#![allow(non_snake_case)]
7#![allow(non_camel_case_types)]
8#![allow(non_upper_case_globals)]
9#![allow(missing_docs)]
10#![allow(clippy::too_many_arguments)]
11#![allow(clippy::type_complexity)]
12#![allow(clippy::upper_case_acronyms)]
13#![allow(clippy::identity_op)]
14#![allow(clippy::missing_safety_doc)]
15#![allow(clippy::doc_lazy_continuation)]
16#![allow(rustdoc::broken_intra_doc_links)]
17#![allow(rustdoc::bare_urls)]
18#![allow(rustdoc::unportable_markdown)]
19#![allow(rustdoc::invalid_html_tags)]
20
21use core::ffi::*;
22use core::ptr::NonNull;
23#[cfg(feature = "objc2")]
24use objc2::__framework_prelude::*;
25
26use crate::*;
27
28/// [Apple's documentation](https://developer.apple.com/documentation/dispatch/dispatch_api_version?language=objc)
29pub const DISPATCH_API_VERSION: c_uint = 20181008;
30impl DispatchTime {
31    /// Create a dispatch_time_t relative to the current value of the default or
32    /// wall time clock, or modify an existing dispatch_time_t.
33    ///
34    ///
35    /// On Apple platforms, the default clock is based on mach_absolute_time().
36    ///
37    ///
38    /// Parameter `when`: An optional dispatch_time_t to add nanoseconds to. If DISPATCH_TIME_NOW is
39    /// passed, then dispatch_time() will use the default clock (which is based on
40    /// mach_absolute_time() on Apple platforms). If DISPATCH_WALLTIME_NOW is used,
41    /// dispatch_time() will use the value returned by gettimeofday(3).
42    /// dispatch_time(DISPATCH_WALLTIME_NOW, delta) is equivalent to
43    /// dispatch_walltime(NULL, delta).
44    ///
45    ///
46    /// Parameter `delta`: Nanoseconds to add.
47    ///
48    ///
49    /// Returns: A new dispatch_time_t.
50    #[doc(alias = "dispatch_time")]
51    #[must_use]
52    #[inline]
53    pub fn time(self: DispatchTime, delta: i64) -> DispatchTime {
54        extern "C" {
55            fn dispatch_time(when: DispatchTime, delta: i64) -> DispatchTime;
56        }
57        unsafe { dispatch_time(self, delta) }
58    }
59
60    /// Create a dispatch_time_t using the wall clock.
61    ///
62    ///
63    /// On Mac OS X the wall clock is based on gettimeofday(3).
64    ///
65    ///
66    /// Parameter `when`: A struct timespec to add time to. If NULL is passed, then
67    /// dispatch_walltime() will use the result of gettimeofday(3).
68    /// dispatch_walltime(NULL, delta) returns the same value as
69    /// dispatch_time(DISPATCH_WALLTIME_NOW, delta).
70    ///
71    ///
72    /// Parameter `delta`: Nanoseconds to add.
73    ///
74    ///
75    /// Returns: A new dispatch_time_t.
76    #[doc(alias = "dispatch_walltime")]
77    #[cfg(feature = "libc")]
78    #[must_use]
79    #[inline]
80    pub unsafe fn walltime(when: *const libc::timespec, delta: i64) -> DispatchTime {
81        extern "C" {
82            fn dispatch_walltime(when: *const libc::timespec, delta: i64) -> DispatchTime;
83        }
84        unsafe { dispatch_walltime(when, delta) }
85    }
86}
87
88/// The type of blocks submitted to dispatch queues, which take no arguments
89/// and have no return value.
90///
91///
92/// When not building with Objective-C ARC, a block object allocated on or
93/// copied to the heap must be released with a -[release] message or the
94/// Block_release() function.
95///
96/// The declaration of a block literal allocates storage on the stack.
97/// Therefore, this is an invalid construct:
98/// <code>
99/// dispatch_block_t block;
100/// if (x) {
101/// block = ^{ printf("true\n"); };
102/// } else {
103/// block = ^{ printf("false\n"); };
104/// }
105/// block(); // unsafe!!!
106/// </code>
107///
108/// What is happening behind the scenes:
109/// <code>
110/// if (x) {
111/// struct Block __tmp_1 = ...; // setup details
112/// block =
113/// &
114/// __tmp_1;
115/// } else {
116/// struct Block __tmp_2 = ...; // setup details
117/// block =
118/// &
119/// __tmp_2;
120/// }
121/// </code>
122///
123/// As the example demonstrates, the address of a stack variable is escaping the
124/// scope in which it is allocated. That is a classic C bug.
125///
126/// Instead, the block literal must be copied to the heap with the Block_copy()
127/// function or by sending it a -[copy] message.
128///
129/// See also [Apple's documentation](https://developer.apple.com/documentation/dispatch/dispatch_block_t?language=objc)
130#[cfg(feature = "block2")]
131pub type dispatch_block_t = *mut block2::DynBlock<dyn Fn()>;
132
133extern "C" {
134    /// Increment the reference count of a dispatch object.
135    ///
136    ///
137    /// Calls to dispatch_retain() must be balanced with calls to
138    /// dispatch_release().
139    ///
140    ///
141    /// Parameter `object`: The object to retain.
142    /// The result of passing NULL in this parameter is undefined.
143    pub fn dispatch_retain(object: NonNull<dispatch_object_s>);
144}
145
146extern "C" {
147    /// Decrement the reference count of a dispatch object.
148    ///
149    ///
150    /// A dispatch object is asynchronously deallocated once all references are
151    /// released (i.e. the reference count becomes zero). The system does not
152    /// guarantee that a given client is the last or only reference to a given
153    /// object.
154    ///
155    ///
156    /// Parameter `object`: The object to release.
157    /// The result of passing NULL in this parameter is undefined.
158    pub fn dispatch_release(object: NonNull<dispatch_object_s>);
159}
160
161/// Returns the application defined context of the object.
162///
163///
164/// Parameter `object`: The result of passing NULL in this parameter is undefined.
165///
166///
167/// Returns: The context of the object; may be NULL.
168#[must_use]
169#[inline]
170pub extern "C" fn dispatch_get_context(object: NonNull<dispatch_object_s>) -> *mut c_void {
171    extern "C" {
172        fn dispatch_get_context(object: NonNull<dispatch_object_s>) -> *mut c_void;
173    }
174    unsafe { dispatch_get_context(object) }
175}
176
177extern "C" {
178    /// Associates an application defined context with the object.
179    ///
180    ///
181    /// Parameter `object`: The result of passing NULL in this parameter is undefined.
182    ///
183    ///
184    /// Parameter `context`: The new client defined context for the object. This may be NULL.
185    pub fn dispatch_set_context(object: NonNull<dispatch_object_s>, context: *mut c_void);
186}
187
188extern "C" {
189    /// Set the finalizer function for a dispatch object.
190    ///
191    ///
192    /// Parameter `object`: The dispatch object to modify.
193    /// The result of passing NULL in this parameter is undefined.
194    ///
195    ///
196    /// Parameter `finalizer`: The finalizer function pointer.
197    ///
198    ///
199    /// A dispatch object's finalizer will be invoked on the object's target queue
200    /// after all references to the object have been released. This finalizer may be
201    /// used by the application to release any resources associated with the object,
202    /// such as freeing the object's context.
203    /// The context parameter passed to the finalizer function is the current
204    /// context of the dispatch object at the time the finalizer call is made.
205    pub fn dispatch_set_finalizer_f(
206        object: NonNull<dispatch_object_s>,
207        finalizer: dispatch_function_t,
208    );
209}
210
211/// Activates the specified dispatch object.
212///
213///
214/// Dispatch objects such as queues and sources may be created in an inactive
215/// state. Objects in this state have to be activated before any blocks
216/// associated with them will be invoked.
217///
218/// The target queue of inactive objects can be changed using
219/// dispatch_set_target_queue(). Change of target queue is no longer permitted
220/// once an initially inactive object has been activated.
221///
222/// Calling dispatch_activate() on an active object has no effect.
223/// Releasing the last reference count on an inactive object is undefined.
224///
225///
226/// Parameter `object`: The object to be activated.
227/// The result of passing NULL in this parameter is undefined.
228#[inline]
229pub extern "C" fn dispatch_activate(object: NonNull<dispatch_object_s>) {
230    extern "C" {
231        fn dispatch_activate(object: NonNull<dispatch_object_s>);
232    }
233    unsafe { dispatch_activate(object) }
234}
235
236/// Suspends the invocation of blocks on a dispatch object.
237///
238///
239/// A suspended object will not invoke any blocks associated with it. The
240/// suspension of an object will occur after any running block associated with
241/// the object completes.
242///
243/// Calls to dispatch_suspend() must be balanced with calls
244/// to dispatch_resume().
245///
246///
247/// Parameter `object`: The object to be suspended.
248/// The result of passing NULL in this parameter is undefined.
249#[inline]
250pub extern "C" fn dispatch_suspend(object: NonNull<dispatch_object_s>) {
251    extern "C" {
252        fn dispatch_suspend(object: NonNull<dispatch_object_s>);
253    }
254    unsafe { dispatch_suspend(object) }
255}
256
257/// Resumes the invocation of blocks on a dispatch object.
258///
259///
260/// Dispatch objects can be suspended with dispatch_suspend(), which increments
261/// an internal suspension count. dispatch_resume() is the inverse operation,
262/// and consumes suspension counts. When the last suspension count is consumed,
263/// blocks associated with the object will be invoked again.
264///
265/// For backward compatibility reasons, dispatch_resume() on an inactive and not
266/// otherwise suspended dispatch source object has the same effect as calling
267/// dispatch_activate(). For new code, using dispatch_activate() is preferred.
268///
269/// If the specified object has zero suspension count and is not an inactive
270/// source, this function will result in an assertion and the process being
271/// terminated.
272///
273///
274/// Parameter `object`: The object to be resumed.
275/// The result of passing NULL in this parameter is undefined.
276#[inline]
277pub extern "C" fn dispatch_resume(object: NonNull<dispatch_object_s>) {
278    extern "C" {
279        fn dispatch_resume(object: NonNull<dispatch_object_s>);
280    }
281    unsafe { dispatch_resume(object) }
282}
283
284extern "C" {
285    /// Sets the QOS class floor on a dispatch queue, source or workloop.
286    ///
287    ///
288    /// The QOS class of workitems submitted to this object asynchronously will be
289    /// elevated to at least the specified QOS class floor. The QOS of the workitem
290    /// will be used if higher than the floor even when the workitem has been created
291    /// without "ENFORCE" semantics.
292    ///
293    /// Setting the QOS class floor is equivalent to the QOS effects of configuring
294    /// a queue whose target queue has a QoS class set to the same value.
295    ///
296    ///
297    /// Parameter `object`: A dispatch queue, workloop, or source to configure.
298    /// The object must be inactive.
299    ///
300    /// Passing another object type or an object that has been activated is undefined
301    /// and will cause the process to be terminated.
302    ///
303    ///
304    /// Parameter `qos_class`: A QOS class value:
305    /// - QOS_CLASS_USER_INTERACTIVE
306    /// - QOS_CLASS_USER_INITIATED
307    /// - QOS_CLASS_DEFAULT
308    /// - QOS_CLASS_UTILITY
309    /// - QOS_CLASS_BACKGROUND
310    /// Passing any other value is undefined.
311    ///
312    ///
313    /// Parameter `relative_priority`: A relative priority within the QOS class. This value is a negative
314    /// offset from the maximum supported scheduler priority for the given class.
315    /// Passing a value greater than zero or less than QOS_MIN_RELATIVE_PRIORITY
316    /// is undefined.
317    pub fn dispatch_set_qos_class_floor(
318        object: NonNull<dispatch_object_s>,
319        qos_class: DispatchQoS,
320        relative_priority: c_int,
321    );
322}
323
324impl DispatchQueue {
325    #[doc(alias = "dispatch_async")]
326    #[cfg(feature = "block2")]
327    #[inline]
328    pub unsafe fn exec_async_with_block(self: &DispatchQueue, block: dispatch_block_t) {
329        extern "C" {
330            fn dispatch_async(queue: &DispatchQueue, block: dispatch_block_t);
331        }
332        unsafe { dispatch_async(self, block) }
333    }
334
335    /// Submits a function for asynchronous execution on a dispatch queue.
336    ///
337    ///
338    /// See dispatch_async() for details.
339    ///
340    ///
341    /// Parameter `queue`: The target dispatch queue to which the function is submitted.
342    /// The system will hold a reference on the target queue until the function
343    /// has returned.
344    /// The result of passing NULL in this parameter is undefined.
345    ///
346    ///
347    /// Parameter `context`: The application-defined context parameter to pass to the function.
348    ///
349    ///
350    /// Parameter `work`: The application-defined function to invoke on the target queue. The first
351    /// parameter passed to this function is the context provided to
352    /// dispatch_async_f().
353    /// The result of passing NULL in this parameter is undefined.
354    #[doc(alias = "dispatch_async_f")]
355    #[inline]
356    pub unsafe fn exec_async_f(
357        self: &DispatchQueue,
358        context: *mut c_void,
359        work: dispatch_function_t,
360    ) {
361        extern "C" {
362            fn dispatch_async_f(
363                queue: &DispatchQueue,
364                context: *mut c_void,
365                work: dispatch_function_t,
366            );
367        }
368        unsafe { dispatch_async_f(self, context, work) }
369    }
370
371    #[doc(alias = "dispatch_sync")]
372    #[cfg(feature = "block2")]
373    #[inline]
374    pub unsafe fn exec_sync_with_block(self: &DispatchQueue, block: dispatch_block_t) {
375        extern "C" {
376            fn dispatch_sync(queue: &DispatchQueue, block: dispatch_block_t);
377        }
378        unsafe { dispatch_sync(self, block) }
379    }
380
381    /// Submits a function for synchronous execution on a dispatch queue.
382    ///
383    ///
384    /// See dispatch_sync() for details.
385    ///
386    ///
387    /// Parameter `queue`: The target dispatch queue to which the function is submitted.
388    /// The result of passing NULL in this parameter is undefined.
389    ///
390    ///
391    /// Parameter `context`: The application-defined context parameter to pass to the function.
392    ///
393    ///
394    /// Parameter `work`: The application-defined function to invoke on the target queue. The first
395    /// parameter passed to this function is the context provided to
396    /// dispatch_sync_f().
397    /// The result of passing NULL in this parameter is undefined.
398    #[doc(alias = "dispatch_sync_f")]
399    #[inline]
400    pub unsafe fn exec_sync_f(
401        self: &DispatchQueue,
402        context: *mut c_void,
403        work: dispatch_function_t,
404    ) {
405        extern "C" {
406            fn dispatch_sync_f(
407                queue: &DispatchQueue,
408                context: *mut c_void,
409                work: dispatch_function_t,
410            );
411        }
412        unsafe { dispatch_sync_f(self, context, work) }
413    }
414
415    #[doc(alias = "dispatch_async_and_wait")]
416    #[cfg(feature = "block2")]
417    #[inline]
418    pub unsafe fn exec_sync_and_wait_with_block(self: &DispatchQueue, block: dispatch_block_t) {
419        extern "C" {
420            fn dispatch_async_and_wait(queue: &DispatchQueue, block: dispatch_block_t);
421        }
422        unsafe { dispatch_async_and_wait(self, block) }
423    }
424
425    /// Submits a function for synchronous execution on a dispatch queue.
426    ///
427    ///
428    /// See dispatch_async_and_wait() for details.
429    ///
430    ///
431    /// Parameter `queue`: The target dispatch queue to which the function is submitted.
432    /// The result of passing NULL in this parameter is undefined.
433    ///
434    ///
435    /// Parameter `context`: The application-defined context parameter to pass to the function.
436    ///
437    ///
438    /// Parameter `work`: The application-defined function to invoke on the target queue. The first
439    /// parameter passed to this function is the context provided to
440    /// dispatch_async_and_wait_f().
441    /// The result of passing NULL in this parameter is undefined.
442    #[doc(alias = "dispatch_async_and_wait_f")]
443    #[inline]
444    pub unsafe fn exec_sync_and_wait_f(
445        self: &DispatchQueue,
446        context: *mut c_void,
447        work: dispatch_function_t,
448    ) {
449        extern "C" {
450            fn dispatch_async_and_wait_f(
451                queue: &DispatchQueue,
452                context: *mut c_void,
453                work: dispatch_function_t,
454            );
455        }
456        unsafe { dispatch_async_and_wait_f(self, context, work) }
457    }
458
459    #[doc(alias = "dispatch_apply")]
460    #[cfg(feature = "block2")]
461    #[inline]
462    pub fn apply_with_block(
463        iterations: usize,
464        queue: Option<&DispatchQueue>,
465        block: &block2::DynBlock<dyn Fn(usize)>,
466    ) {
467        extern "C" {
468            fn dispatch_apply(
469                iterations: usize,
470                queue: Option<&DispatchQueue>,
471                block: &block2::DynBlock<dyn Fn(usize)>,
472            );
473        }
474        unsafe { dispatch_apply(iterations, queue, block) }
475    }
476
477    /// Submits a function to a dispatch queue for parallel invocation.
478    ///
479    ///
480    /// See dispatch_apply() for details.
481    ///
482    ///
483    /// Parameter `iterations`: The number of iterations to perform.
484    ///
485    ///
486    /// Parameter `queue`: The dispatch queue to which the function is submitted.
487    /// The preferred value to pass is DISPATCH_APPLY_AUTO to automatically use
488    /// a queue appropriate for the calling thread.
489    ///
490    ///
491    /// Parameter `context`: The application-defined context parameter to pass to the function.
492    ///
493    ///
494    /// Parameter `work`: The application-defined function to invoke on the specified queue. The first
495    /// parameter passed to this function is the context provided to
496    /// dispatch_apply_f(). The second parameter passed to this function is the
497    /// current index of iteration.
498    /// The result of passing NULL in this parameter is undefined.
499    #[doc(alias = "dispatch_apply_f")]
500    #[inline]
501    pub unsafe fn apply_f(
502        iterations: usize,
503        queue: Option<&DispatchQueue>,
504        context: *mut c_void,
505        work: unsafe extern "C-unwind" fn(*mut c_void, usize),
506    ) {
507        extern "C" {
508            fn dispatch_apply_f(
509                iterations: usize,
510                queue: Option<&DispatchQueue>,
511                context: *mut c_void,
512                work: unsafe extern "C-unwind" fn(*mut c_void, usize),
513            );
514        }
515        unsafe { dispatch_apply_f(iterations, queue, context, work) }
516    }
517
518    /// Returns the queue on which the currently executing block is running.
519    ///
520    ///
521    /// Returns the queue on which the currently executing block is running.
522    ///
523    /// When dispatch_get_current_queue() is called outside of the context of a
524    /// submitted block, it will return the default concurrent queue.
525    ///
526    /// Recommended for debugging and logging purposes only:
527    /// The code must not make any assumptions about the queue returned, unless it
528    /// is one of the global queues or a queue the code has itself created.
529    /// The code must not assume that synchronous execution onto a queue is safe
530    /// from deadlock if that queue is not the one returned by
531    /// dispatch_get_current_queue().
532    ///
533    /// When dispatch_get_current_queue() is called on the main thread, it may
534    /// or may not return the same value as dispatch_get_main_queue(). Comparing
535    /// the two is not a valid way to test whether code is executing on the
536    /// main thread (see dispatch_assert_queue() and dispatch_assert_queue_not()).
537    ///
538    /// This function is deprecated and will be removed in a future release.
539    ///
540    ///
541    /// Returns: Returns the current queue.
542    #[doc(alias = "dispatch_get_current_queue")]
543    #[deprecated = "unsupported interface"]
544    #[must_use]
545    #[inline]
546    pub fn current() -> DispatchRetained<DispatchQueue> {
547        extern "C" {
548            fn dispatch_get_current_queue() -> Option<NonNull<DispatchQueue>>;
549        }
550        let ret = unsafe { dispatch_get_current_queue() };
551        let ret =
552            ret.expect("function was marked as returning non-null, but actually returned NULL");
553        unsafe { DispatchRetained::retain(ret) }
554    }
555}
556
557extern "C" {
558    /// [Apple's documentation](https://developer.apple.com/documentation/dispatch/_dispatch_main_q?language=objc)
559    pub static _dispatch_main_q: DispatchQueue;
560}
561
562/// Returns a well-known global concurrent queue of a given quality of service
563/// class.
564///
565///
566/// See dispatch_queue_global_t.
567///
568///
569/// Parameter `identifier`: A quality of service class defined in qos_class_t or a priority defined in
570/// dispatch_queue_priority_t.
571///
572/// It is recommended to use quality of service class values to identify the
573/// well-known global concurrent queues:
574/// - QOS_CLASS_USER_INTERACTIVE
575/// - QOS_CLASS_USER_INITIATED
576/// - QOS_CLASS_DEFAULT
577/// - QOS_CLASS_UTILITY
578/// - QOS_CLASS_BACKGROUND
579///
580/// The global concurrent queues may still be identified by their priority,
581/// which map to the following QOS classes:
582/// - DISPATCH_QUEUE_PRIORITY_HIGH:         QOS_CLASS_USER_INITIATED
583/// - DISPATCH_QUEUE_PRIORITY_DEFAULT:      QOS_CLASS_DEFAULT
584/// - DISPATCH_QUEUE_PRIORITY_LOW:          QOS_CLASS_UTILITY
585/// - DISPATCH_QUEUE_PRIORITY_BACKGROUND:   QOS_CLASS_BACKGROUND
586///
587///
588/// Parameter `flags`: Reserved for future use. Passing any value other than zero may result in
589/// a NULL return value.
590///
591///
592/// Returns: Returns the requested global queue or NULL if the requested global queue
593/// does not exist.
594#[must_use]
595#[inline]
596pub extern "C" fn dispatch_get_global_queue(
597    identifier: isize,
598    flags: usize,
599) -> DispatchRetained<DispatchQueue> {
600    extern "C" {
601        fn dispatch_get_global_queue(
602            identifier: isize,
603            flags: usize,
604        ) -> Option<NonNull<DispatchQueue>>;
605    }
606    let ret = unsafe { dispatch_get_global_queue(identifier, flags) };
607    let ret = ret.expect("function was marked as returning non-null, but actually returned NULL");
608    unsafe { DispatchRetained::retain(ret) }
609}
610
611extern "C" {
612    /// [Apple's documentation](https://developer.apple.com/documentation/dispatch/_dispatch_queue_attr_concurrent?language=objc)
613    pub static _dispatch_queue_attr_concurrent: DispatchQueueAttr;
614}
615
616impl DispatchQueueAttr {
617    /// Returns an attribute value which may be provided to dispatch_queue_create()
618    /// or dispatch_queue_create_with_target(), in order to make the created queue
619    /// initially inactive.
620    ///
621    ///
622    /// Dispatch queues may be created in an inactive state. Queues in this state
623    /// have to be activated before any blocks associated with them will be invoked.
624    ///
625    /// A queue in inactive state cannot be deallocated, dispatch_activate() must be
626    /// called before the last reference to a queue created with this attribute is
627    /// released.
628    ///
629    /// The target queue of a queue in inactive state can be changed using
630    /// dispatch_set_target_queue(). Change of target queue is no longer permitted
631    /// once an initially inactive queue has been activated.
632    ///
633    ///
634    /// Parameter `attr`: A queue attribute value to be combined with the initially inactive attribute.
635    ///
636    ///
637    /// Returns: Returns an attribute value which may be provided to dispatch_queue_create()
638    /// and dispatch_queue_create_with_target().
639    /// The new value combines the attributes specified by the 'attr' parameter with
640    /// the initially inactive attribute.
641    #[doc(alias = "dispatch_queue_attr_make_initially_inactive")]
642    #[must_use]
643    #[inline]
644    pub fn new_initially_inactive(
645        attr: Option<&DispatchQueueAttr>,
646    ) -> DispatchRetained<DispatchQueueAttr> {
647        extern "C" {
648            fn dispatch_queue_attr_make_initially_inactive(
649                attr: Option<&DispatchQueueAttr>,
650            ) -> Option<NonNull<DispatchQueueAttr>>;
651        }
652        let ret = unsafe { dispatch_queue_attr_make_initially_inactive(attr) };
653        let ret =
654            ret.expect("function was marked as returning non-null, but actually returned NULL");
655        unsafe { DispatchRetained::retain(ret) }
656    }
657}
658
659/// Values to pass to the dispatch_queue_attr_make_with_autorelease_frequency()
660/// function.
661///
662///
663/// Dispatch queues with this autorelease frequency inherit the behavior from
664/// their target queue. This is the default behavior for manually created queues.
665///
666///
667/// Dispatch queues with this autorelease frequency push and pop an autorelease
668/// pool around the execution of every block that was submitted to it
669/// asynchronously.
670///
671/// See: dispatch_queue_attr_make_with_autorelease_frequency().
672///
673///
674/// Dispatch queues with this autorelease frequency never set up an individual
675/// autorelease pool around the execution of a block that is submitted to it
676/// asynchronously. This is the behavior of the global concurrent queues.
677///
678/// See also [Apple's documentation](https://developer.apple.com/documentation/dispatch/dispatchautoreleasefrequency?language=objc)
679#[doc(alias = "dispatch_autorelease_frequency_t")] // NS_ENUM
680#[repr(transparent)]
681#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
682pub struct DispatchAutoReleaseFrequency(pub c_ulong);
683impl DispatchAutoReleaseFrequency {
684    /// Values to pass to the dispatch_queue_attr_make_with_autorelease_frequency()
685    /// function.
686    ///
687    ///
688    /// Dispatch queues with this autorelease frequency inherit the behavior from
689    /// their target queue. This is the default behavior for manually created queues.
690    ///
691    ///
692    /// Dispatch queues with this autorelease frequency push and pop an autorelease
693    /// pool around the execution of every block that was submitted to it
694    /// asynchronously.
695    ///
696    /// See: dispatch_queue_attr_make_with_autorelease_frequency().
697    ///
698    ///
699    /// Dispatch queues with this autorelease frequency never set up an individual
700    /// autorelease pool around the execution of a block that is submitted to it
701    /// asynchronously. This is the behavior of the global concurrent queues.
702    #[doc(alias = "DISPATCH_AUTORELEASE_FREQUENCY_INHERIT")]
703    pub const INHERIT: Self = Self(0);
704    /// Values to pass to the dispatch_queue_attr_make_with_autorelease_frequency()
705    /// function.
706    ///
707    ///
708    /// Dispatch queues with this autorelease frequency inherit the behavior from
709    /// their target queue. This is the default behavior for manually created queues.
710    ///
711    ///
712    /// Dispatch queues with this autorelease frequency push and pop an autorelease
713    /// pool around the execution of every block that was submitted to it
714    /// asynchronously.
715    ///
716    /// See: dispatch_queue_attr_make_with_autorelease_frequency().
717    ///
718    ///
719    /// Dispatch queues with this autorelease frequency never set up an individual
720    /// autorelease pool around the execution of a block that is submitted to it
721    /// asynchronously. This is the behavior of the global concurrent queues.
722    #[doc(alias = "DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM")]
723    pub const WORK_ITEM: Self = Self(1);
724    /// Values to pass to the dispatch_queue_attr_make_with_autorelease_frequency()
725    /// function.
726    ///
727    ///
728    /// Dispatch queues with this autorelease frequency inherit the behavior from
729    /// their target queue. This is the default behavior for manually created queues.
730    ///
731    ///
732    /// Dispatch queues with this autorelease frequency push and pop an autorelease
733    /// pool around the execution of every block that was submitted to it
734    /// asynchronously.
735    ///
736    /// See: dispatch_queue_attr_make_with_autorelease_frequency().
737    ///
738    ///
739    /// Dispatch queues with this autorelease frequency never set up an individual
740    /// autorelease pool around the execution of a block that is submitted to it
741    /// asynchronously. This is the behavior of the global concurrent queues.
742    #[doc(alias = "DISPATCH_AUTORELEASE_FREQUENCY_NEVER")]
743    pub const NEVER: Self = Self(2);
744}
745
746#[cfg(feature = "objc2")]
747unsafe impl Encode for DispatchAutoReleaseFrequency {
748    const ENCODING: Encoding = Encoding::C_ULONG;
749}
750
751#[cfg(feature = "objc2")]
752unsafe impl RefEncode for DispatchAutoReleaseFrequency {
753    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
754}
755
756impl DispatchQueueAttr {
757    /// Returns a dispatch queue attribute value with the autorelease frequency
758    /// set to the specified value.
759    ///
760    ///
761    /// When a queue uses the per-workitem autorelease frequency (either directly
762    /// or inherited from its target queue), any block submitted asynchronously to
763    /// this queue (via dispatch_async(), dispatch_barrier_async(),
764    /// dispatch_group_notify(), etc...) is executed as if surrounded by a individual
765    /// Objective-C
766    /// <code>
767    /// objc2::rc::autoreleasepool</code>
768    /// scope.
769    ///
770    /// Autorelease frequency has no effect on blocks that are submitted
771    /// synchronously to a queue (via dispatch_sync(), dispatch_barrier_sync()).
772    ///
773    /// The global concurrent queues have the DISPATCH_AUTORELEASE_FREQUENCY_NEVER
774    /// behavior. Manually created dispatch queues use
775    /// DISPATCH_AUTORELEASE_FREQUENCY_INHERIT by default.
776    ///
777    /// Queues created with this attribute cannot change target queues after having
778    /// been activated. See dispatch_set_target_queue() and dispatch_activate().
779    ///
780    ///
781    /// Parameter `attr`: A queue attribute value to be combined with the specified autorelease
782    /// frequency or NULL.
783    ///
784    ///
785    /// Parameter `frequency`: The requested autorelease frequency.
786    ///
787    ///
788    /// Returns: Returns an attribute value which may be provided to dispatch_queue_create()
789    /// or NULL if an invalid autorelease frequency was requested.
790    /// This new value combines the attributes specified by the 'attr' parameter and
791    /// the chosen autorelease frequency.
792    #[doc(alias = "dispatch_queue_attr_make_with_autorelease_frequency")]
793    #[must_use]
794    #[inline]
795    pub fn with_autorelease_frequency(
796        attr: Option<&DispatchQueueAttr>,
797        frequency: DispatchAutoReleaseFrequency,
798    ) -> DispatchRetained<DispatchQueueAttr> {
799        extern "C" {
800            fn dispatch_queue_attr_make_with_autorelease_frequency(
801                attr: Option<&DispatchQueueAttr>,
802                frequency: DispatchAutoReleaseFrequency,
803            ) -> Option<NonNull<DispatchQueueAttr>>;
804        }
805        let ret = unsafe { dispatch_queue_attr_make_with_autorelease_frequency(attr, frequency) };
806        let ret =
807            ret.expect("function was marked as returning non-null, but actually returned NULL");
808        unsafe { DispatchRetained::retain(ret) }
809    }
810
811    /// Returns an attribute value which may be provided to dispatch_queue_create()
812    /// or dispatch_queue_create_with_target(), in order to assign a QOS class and
813    /// relative priority to the queue.
814    ///
815    ///
816    /// When specified in this manner, the QOS class and relative priority take
817    /// precedence over those inherited from the dispatch queue's target queue (if
818    /// any) as long that does not result in a lower QOS class and relative priority.
819    ///
820    /// The global queue priorities map to the following QOS classes:
821    /// - DISPATCH_QUEUE_PRIORITY_HIGH:         QOS_CLASS_USER_INITIATED
822    /// - DISPATCH_QUEUE_PRIORITY_DEFAULT:      QOS_CLASS_DEFAULT
823    /// - DISPATCH_QUEUE_PRIORITY_LOW:          QOS_CLASS_UTILITY
824    /// - DISPATCH_QUEUE_PRIORITY_BACKGROUND:   QOS_CLASS_BACKGROUND
825    ///
826    /// Example:
827    /// <code>
828    /// dispatch_queue_t queue;
829    /// dispatch_queue_attr_t attr;
830    /// attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL,
831    /// QOS_CLASS_UTILITY, 0);
832    /// queue = dispatch_queue_create("com.example.myqueue", attr);
833    /// </code>
834    ///
835    /// The QOS class and relative priority set this way on a queue have no effect on
836    /// blocks that are submitted synchronously to a queue (via dispatch_sync(),
837    /// dispatch_barrier_sync()).
838    ///
839    ///
840    /// Parameter `attr`: A queue attribute value to be combined with the QOS class, or NULL.
841    ///
842    ///
843    /// Parameter `qos_class`: A QOS class value:
844    /// - QOS_CLASS_USER_INTERACTIVE
845    /// - QOS_CLASS_USER_INITIATED
846    /// - QOS_CLASS_DEFAULT
847    /// - QOS_CLASS_UTILITY
848    /// - QOS_CLASS_BACKGROUND
849    /// Passing any other value results in NULL being returned.
850    ///
851    ///
852    /// Parameter `relative_priority`: A relative priority within the QOS class. This value is a negative
853    /// offset from the maximum supported scheduler priority for the given class.
854    /// Passing a value greater than zero or less than QOS_MIN_RELATIVE_PRIORITY
855    /// results in NULL being returned.
856    ///
857    ///
858    /// Returns: Returns an attribute value which may be provided to dispatch_queue_create()
859    /// and dispatch_queue_create_with_target(), or NULL if an invalid QOS class was
860    /// requested.
861    /// The new value combines the attributes specified by the 'attr' parameter and
862    /// the new QOS class and relative priority.
863    #[doc(alias = "dispatch_queue_attr_make_with_qos_class")]
864    #[must_use]
865    #[inline]
866    pub fn with_qos_class(
867        attr: Option<&DispatchQueueAttr>,
868        qos_class: DispatchQoS,
869        relative_priority: c_int,
870    ) -> DispatchRetained<DispatchQueueAttr> {
871        extern "C" {
872            fn dispatch_queue_attr_make_with_qos_class(
873                attr: Option<&DispatchQueueAttr>,
874                qos_class: DispatchQoS,
875                relative_priority: c_int,
876            ) -> Option<NonNull<DispatchQueueAttr>>;
877        }
878        let ret =
879            unsafe { dispatch_queue_attr_make_with_qos_class(attr, qos_class, relative_priority) };
880        let ret =
881            ret.expect("function was marked as returning non-null, but actually returned NULL");
882        unsafe { DispatchRetained::retain(ret) }
883    }
884}
885
886impl DispatchQueue {
887    /// Creates a new dispatch queue with a specified target queue.
888    ///
889    ///
890    /// Dispatch queues created with the DISPATCH_QUEUE_SERIAL or a NULL attribute
891    /// invoke blocks serially in FIFO order.
892    ///
893    /// Dispatch queues created with the DISPATCH_QUEUE_CONCURRENT attribute may
894    /// invoke blocks concurrently (similarly to the global concurrent queues, but
895    /// potentially with more overhead), and support barrier blocks submitted with
896    /// the dispatch barrier API, which e.g. enables the implementation of efficient
897    /// reader-writer schemes.
898    ///
899    /// When a dispatch queue is no longer needed, it should be released with
900    /// dispatch_release(). Note that any pending blocks submitted asynchronously to
901    /// a queue will hold a reference to that queue. Therefore a queue will not be
902    /// deallocated until all pending blocks have finished.
903    ///
904    /// When using a dispatch queue attribute
905    /// _attr_specifying a QoS class (derived
906    /// from the result of dispatch_queue_attr_make_with_qos_class()), passing the
907    /// result of dispatch_get_global_queue() in
908    /// _target_will ignore the QoS class
909    /// of that global queue and will use the global queue with the QoS class
910    /// specified by attr instead.
911    ///
912    /// Queues created with dispatch_queue_create_with_target() cannot have their
913    /// target queue changed, unless created inactive (See
914    /// dispatch_queue_attr_make_initially_inactive()), in which case the target
915    /// queue can be changed until the newly created queue is activated with
916    /// dispatch_activate().
917    ///
918    ///
919    /// Parameter `label`: A string label to attach to the queue.
920    /// This parameter is optional and may be NULL.
921    ///
922    ///
923    /// Parameter `attr`: A predefined attribute such as DISPATCH_QUEUE_SERIAL,
924    /// DISPATCH_QUEUE_CONCURRENT, or the result of a call to
925    /// a dispatch_queue_attr_make_with_* function.
926    ///
927    ///
928    /// Parameter `target`: The target queue for the newly created queue. The target queue is retained.
929    /// If this parameter is DISPATCH_TARGET_QUEUE_DEFAULT, sets the queue's target
930    /// queue to the default target queue for the given queue type.
931    ///
932    ///
933    /// Returns: The newly created dispatch queue.
934    #[doc(alias = "dispatch_queue_create_with_target")]
935    #[must_use]
936    #[inline]
937    pub(crate) unsafe fn __new_with_target(
938        label: *const c_char,
939        attr: Option<&DispatchQueueAttr>,
940        target: Option<&DispatchQueue>,
941    ) -> DispatchRetained<DispatchQueue> {
942        extern "C" {
943            #[cfg_attr(
944                target_vendor = "apple",
945                link_name = "dispatch_queue_create_with_target$V2"
946            )]
947            fn dispatch_queue_create_with_target(
948                label: *const c_char,
949                attr: Option<&DispatchQueueAttr>,
950                target: Option<&DispatchQueue>,
951            ) -> Option<NonNull<DispatchQueue>>;
952        }
953        let ret = unsafe { dispatch_queue_create_with_target(label, attr, target) };
954        let ret =
955            ret.expect("function was marked as returning non-null, but actually returned NULL");
956        unsafe { DispatchRetained::from_raw(ret) }
957    }
958
959    /// Creates a new dispatch queue to which blocks may be submitted.
960    ///
961    ///
962    /// Dispatch queues created with the DISPATCH_QUEUE_SERIAL or a NULL attribute
963    /// invoke blocks serially in FIFO order.
964    ///
965    /// Dispatch queues created with the DISPATCH_QUEUE_CONCURRENT attribute may
966    /// invoke blocks concurrently (similarly to the global concurrent queues, but
967    /// potentially with more overhead), and support barrier blocks submitted with
968    /// the dispatch barrier API, which e.g. enables the implementation of efficient
969    /// reader-writer schemes.
970    ///
971    /// When a dispatch queue is no longer needed, it should be released with
972    /// dispatch_release(). Note that any pending blocks submitted asynchronously to
973    /// a queue will hold a reference to that queue. Therefore a queue will not be
974    /// deallocated until all pending blocks have finished.
975    ///
976    /// Passing the result of the dispatch_queue_attr_make_with_qos_class() function
977    /// to the attr parameter of this function allows a quality of service class and
978    /// relative priority to be specified for the newly created queue.
979    /// The quality of service class so specified takes precedence over the quality
980    /// of service class of the newly created dispatch queue's target queue (if any)
981    /// as long that does not result in a lower QOS class and relative priority.
982    ///
983    /// When no quality of service class is specified, the target queue of a newly
984    /// created dispatch queue is the default priority global concurrent queue.
985    ///
986    /// Unless explicitly specified via the attribute, queues are created active.
987    ///
988    ///
989    /// Parameter `label`: A string label to attach to the queue.
990    /// This parameter is optional and may be NULL.
991    ///
992    ///
993    /// Parameter `attr`: A predefined attribute such as DISPATCH_QUEUE_SERIAL,
994    /// DISPATCH_QUEUE_CONCURRENT, or the result of a call to
995    /// a dispatch_queue_attr_make_with_* function.
996    ///
997    ///
998    /// Returns: The newly created dispatch queue.
999    #[doc(alias = "dispatch_queue_create")]
1000    #[must_use]
1001    #[inline]
1002    pub(crate) unsafe fn __new(
1003        label: *const c_char,
1004        attr: Option<&DispatchQueueAttr>,
1005    ) -> DispatchRetained<DispatchQueue> {
1006        extern "C" {
1007            fn dispatch_queue_create(
1008                label: *const c_char,
1009                attr: Option<&DispatchQueueAttr>,
1010            ) -> Option<NonNull<DispatchQueue>>;
1011        }
1012        let ret = unsafe { dispatch_queue_create(label, attr) };
1013        let ret =
1014            ret.expect("function was marked as returning non-null, but actually returned NULL");
1015        unsafe { DispatchRetained::from_raw(ret) }
1016    }
1017
1018    /// Returns the label of the given queue, as specified when the queue was
1019    /// created, or the empty string if a NULL label was specified.
1020    ///
1021    /// Passing DISPATCH_CURRENT_QUEUE_LABEL will return the label of the current
1022    /// queue.
1023    ///
1024    ///
1025    /// Parameter `queue`: The queue to query, or DISPATCH_CURRENT_QUEUE_LABEL.
1026    ///
1027    ///
1028    /// Returns: The label of the queue.
1029    #[doc(alias = "dispatch_queue_get_label")]
1030    #[must_use]
1031    #[inline]
1032    pub fn label(queue: Option<&DispatchQueue>) -> NonNull<c_char> {
1033        extern "C" {
1034            fn dispatch_queue_get_label(queue: Option<&DispatchQueue>) -> Option<NonNull<c_char>>;
1035        }
1036        let ret = unsafe { dispatch_queue_get_label(queue) };
1037        ret.expect("function was marked as returning non-null, but actually returned NULL")
1038    }
1039
1040    /// Returns the QOS class and relative priority of the given queue.
1041    ///
1042    ///
1043    /// If the given queue was created with an attribute value returned from
1044    /// dispatch_queue_attr_make_with_qos_class(), this function returns the QOS
1045    /// class and relative priority specified at that time; for any other attribute
1046    /// value it returns a QOS class of QOS_CLASS_UNSPECIFIED and a relative
1047    /// priority of 0.
1048    ///
1049    /// If the given queue is one of the global queues, this function returns its
1050    /// assigned QOS class value as documented under dispatch_get_global_queue() and
1051    /// a relative priority of 0; in the case of the main queue it returns the QOS
1052    /// value provided by qos_class_main() and a relative priority of 0.
1053    ///
1054    ///
1055    /// Parameter `queue`: The queue to query.
1056    ///
1057    ///
1058    /// Parameter `relative_priority_ptr`: A pointer to an int variable to be filled with the relative priority offset
1059    /// within the QOS class, or NULL.
1060    ///
1061    ///
1062    /// Returns: A QOS class value:
1063    /// - QOS_CLASS_USER_INTERACTIVE
1064    /// - QOS_CLASS_USER_INITIATED
1065    /// - QOS_CLASS_DEFAULT
1066    /// - QOS_CLASS_UTILITY
1067    /// - QOS_CLASS_BACKGROUND
1068    /// - QOS_CLASS_UNSPECIFIED
1069    #[doc(alias = "dispatch_queue_get_qos_class")]
1070    #[must_use]
1071    #[inline]
1072    pub unsafe fn qos_class(
1073        self: &DispatchQueue,
1074        relative_priority_ptr: *mut c_int,
1075    ) -> DispatchQoS {
1076        extern "C" {
1077            fn dispatch_queue_get_qos_class(
1078                queue: &DispatchQueue,
1079                relative_priority_ptr: *mut c_int,
1080            ) -> DispatchQoS;
1081        }
1082        unsafe { dispatch_queue_get_qos_class(self, relative_priority_ptr) }
1083    }
1084}
1085
1086extern "C" {
1087    /// Sets the target queue for the given object.
1088    ///
1089    ///
1090    /// An object's target queue is responsible for processing the object.
1091    ///
1092    /// When no quality of service class and relative priority is specified for a
1093    /// dispatch queue at the time of creation, a dispatch queue's quality of service
1094    /// class is inherited from its target queue. The dispatch_get_global_queue()
1095    /// function may be used to obtain a target queue of a specific quality of
1096    /// service class, however the use of dispatch_queue_attr_make_with_qos_class()
1097    /// is recommended instead.
1098    ///
1099    /// Blocks submitted to a serial queue whose target queue is another serial
1100    /// queue will not be invoked concurrently with blocks submitted to the target
1101    /// queue or to any other queue with that same target queue.
1102    ///
1103    /// The result of introducing a cycle into the hierarchy of target queues is
1104    /// undefined.
1105    ///
1106    /// A dispatch source's target queue specifies where its event handler and
1107    /// cancellation handler blocks will be submitted.
1108    ///
1109    /// A dispatch I/O channel's target queue specifies where where its I/O
1110    /// operations are executed. If the channel's target queue's priority is set to
1111    /// DISPATCH_QUEUE_PRIORITY_BACKGROUND, then the I/O operations performed by
1112    /// dispatch_io_read() or dispatch_io_write() on that queue will be
1113    /// throttled when there is I/O contention.
1114    ///
1115    /// For all other dispatch object types, the only function of the target queue
1116    /// is to determine where an object's finalizer function is invoked.
1117    ///
1118    /// In general, changing the target queue of an object is an asynchronous
1119    /// operation that doesn't take effect immediately, and doesn't affect blocks
1120    /// already associated with the specified object.
1121    ///
1122    /// However, if an object is inactive at the time dispatch_set_target_queue() is
1123    /// called, then the target queue change takes effect immediately, and will
1124    /// affect blocks already associated with the specified object. After an
1125    /// initially inactive object has been activated, calling
1126    /// dispatch_set_target_queue() results in an assertion and the process being
1127    /// terminated.
1128    ///
1129    /// If a dispatch queue is active and targeted by other dispatch objects,
1130    /// changing its target queue results in undefined behavior.  Instead, it is
1131    /// recommended to create dispatch objects in an inactive state, set up the
1132    /// relevant target queues and then activate them.
1133    ///
1134    ///
1135    /// Parameter `object`: The object to modify.
1136    /// The result of passing NULL in this parameter is undefined.
1137    ///
1138    ///
1139    /// Parameter `queue`: The new target queue for the object. The queue is retained, and the
1140    /// previous target queue, if any, is released.
1141    /// If queue is DISPATCH_TARGET_QUEUE_DEFAULT, set the object's target queue
1142    /// to the default target queue for the given object type.
1143    pub fn dispatch_set_target_queue(
1144        object: NonNull<dispatch_object_s>,
1145        queue: Option<&DispatchQueue>,
1146    );
1147}
1148
1149impl DispatchQueue {
1150    #[doc(alias = "dispatch_after")]
1151    #[cfg(feature = "block2")]
1152    #[inline]
1153    pub unsafe fn exec_after_with_block(
1154        when: DispatchTime,
1155        queue: &DispatchQueue,
1156        block: dispatch_block_t,
1157    ) {
1158        extern "C" {
1159            fn dispatch_after(when: DispatchTime, queue: &DispatchQueue, block: dispatch_block_t);
1160        }
1161        unsafe { dispatch_after(when, queue, block) }
1162    }
1163
1164    /// Schedule a function for execution on a given queue at a specified time.
1165    ///
1166    ///
1167    /// See dispatch_after() for details.
1168    ///
1169    ///
1170    /// Parameter `when`: A temporal milestone returned by dispatch_time() or dispatch_walltime().
1171    ///
1172    ///
1173    /// Parameter `queue`: A queue to which the given function will be submitted at the specified time.
1174    /// The result of passing NULL in this parameter is undefined.
1175    ///
1176    ///
1177    /// Parameter `context`: The application-defined context parameter to pass to the function.
1178    ///
1179    ///
1180    /// Parameter `work`: The application-defined function to invoke on the target queue. The first
1181    /// parameter passed to this function is the context provided to
1182    /// dispatch_after_f().
1183    /// The result of passing NULL in this parameter is undefined.
1184    #[doc(alias = "dispatch_after_f")]
1185    #[inline]
1186    pub unsafe fn exec_after_f(
1187        when: DispatchTime,
1188        queue: &DispatchQueue,
1189        context: *mut c_void,
1190        work: dispatch_function_t,
1191    ) {
1192        extern "C" {
1193            fn dispatch_after_f(
1194                when: DispatchTime,
1195                queue: &DispatchQueue,
1196                context: *mut c_void,
1197                work: dispatch_function_t,
1198            );
1199        }
1200        unsafe { dispatch_after_f(when, queue, context, work) }
1201    }
1202
1203    #[doc(alias = "dispatch_barrier_async")]
1204    #[cfg(feature = "block2")]
1205    #[inline]
1206    pub unsafe fn barrier_async_with_block(self: &DispatchQueue, block: dispatch_block_t) {
1207        extern "C" {
1208            fn dispatch_barrier_async(queue: &DispatchQueue, block: dispatch_block_t);
1209        }
1210        unsafe { dispatch_barrier_async(self, block) }
1211    }
1212
1213    /// Submits a barrier function for asynchronous execution on a dispatch queue.
1214    ///
1215    ///
1216    /// Submits a function to a dispatch queue like dispatch_async_f(), but marks
1217    /// that function as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT
1218    /// queues).
1219    ///
1220    /// See dispatch_async_f() for details and "Dispatch Barrier API" for a
1221    /// description of the barrier semantics.
1222    ///
1223    ///
1224    /// Parameter `queue`: The target dispatch queue to which the function is submitted.
1225    /// The system will hold a reference on the target queue until the function
1226    /// has returned.
1227    /// The result of passing NULL in this parameter is undefined.
1228    ///
1229    ///
1230    /// Parameter `context`: The application-defined context parameter to pass to the function.
1231    ///
1232    ///
1233    /// Parameter `work`: The application-defined function to invoke on the target queue. The first
1234    /// parameter passed to this function is the context provided to
1235    /// dispatch_barrier_async_f().
1236    /// The result of passing NULL in this parameter is undefined.
1237    #[doc(alias = "dispatch_barrier_async_f")]
1238    #[inline]
1239    pub unsafe fn barrier_async_f(
1240        self: &DispatchQueue,
1241        context: *mut c_void,
1242        work: dispatch_function_t,
1243    ) {
1244        extern "C" {
1245            fn dispatch_barrier_async_f(
1246                queue: &DispatchQueue,
1247                context: *mut c_void,
1248                work: dispatch_function_t,
1249            );
1250        }
1251        unsafe { dispatch_barrier_async_f(self, context, work) }
1252    }
1253
1254    #[doc(alias = "dispatch_barrier_sync")]
1255    #[cfg(feature = "block2")]
1256    #[inline]
1257    pub unsafe fn barrier_sync_with_block(self: &DispatchQueue, block: dispatch_block_t) {
1258        extern "C" {
1259            fn dispatch_barrier_sync(queue: &DispatchQueue, block: dispatch_block_t);
1260        }
1261        unsafe { dispatch_barrier_sync(self, block) }
1262    }
1263
1264    /// Submits a barrier function for synchronous execution on a dispatch queue.
1265    ///
1266    ///
1267    /// Submits a function to a dispatch queue like dispatch_sync_f(), but marks that
1268    /// fuction as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT queues).
1269    ///
1270    /// See dispatch_sync_f() for details.
1271    ///
1272    ///
1273    /// Parameter `queue`: The target dispatch queue to which the function is submitted.
1274    /// The result of passing NULL in this parameter is undefined.
1275    ///
1276    ///
1277    /// Parameter `context`: The application-defined context parameter to pass to the function.
1278    ///
1279    ///
1280    /// Parameter `work`: The application-defined function to invoke on the target queue. The first
1281    /// parameter passed to this function is the context provided to
1282    /// dispatch_barrier_sync_f().
1283    /// The result of passing NULL in this parameter is undefined.
1284    #[doc(alias = "dispatch_barrier_sync_f")]
1285    #[inline]
1286    pub unsafe fn barrier_sync_f(
1287        self: &DispatchQueue,
1288        context: *mut c_void,
1289        work: dispatch_function_t,
1290    ) {
1291        extern "C" {
1292            fn dispatch_barrier_sync_f(
1293                queue: &DispatchQueue,
1294                context: *mut c_void,
1295                work: dispatch_function_t,
1296            );
1297        }
1298        unsafe { dispatch_barrier_sync_f(self, context, work) }
1299    }
1300
1301    #[doc(alias = "dispatch_barrier_async_and_wait")]
1302    #[cfg(feature = "block2")]
1303    #[inline]
1304    pub unsafe fn barrier_async_and_wait_with_block(self: &DispatchQueue, block: dispatch_block_t) {
1305        extern "C" {
1306            fn dispatch_barrier_async_and_wait(queue: &DispatchQueue, block: dispatch_block_t);
1307        }
1308        unsafe { dispatch_barrier_async_and_wait(self, block) }
1309    }
1310
1311    /// Submits a function for synchronous execution on a dispatch queue.
1312    ///
1313    ///
1314    /// Submits a function to a dispatch queue like dispatch_async_and_wait_f(), but
1315    /// marks that function as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT
1316    /// queues).
1317    ///
1318    /// See "Dispatch Barrier API" for a description of the barrier semantics.
1319    ///
1320    ///
1321    /// Parameter `queue`: The target dispatch queue to which the function is submitted.
1322    /// The result of passing NULL in this parameter is undefined.
1323    ///
1324    ///
1325    /// Parameter `context`: The application-defined context parameter to pass to the function.
1326    ///
1327    ///
1328    /// Parameter `work`: The application-defined function to invoke on the target queue. The first
1329    /// parameter passed to this function is the context provided to
1330    /// dispatch_barrier_async_and_wait_f().
1331    /// The result of passing NULL in this parameter is undefined.
1332    #[doc(alias = "dispatch_barrier_async_and_wait_f")]
1333    #[inline]
1334    pub unsafe fn barrier_async_and_wait_f(
1335        self: &DispatchQueue,
1336        context: *mut c_void,
1337        work: dispatch_function_t,
1338    ) {
1339        extern "C" {
1340            fn dispatch_barrier_async_and_wait_f(
1341                queue: &DispatchQueue,
1342                context: *mut c_void,
1343                work: dispatch_function_t,
1344            );
1345        }
1346        unsafe { dispatch_barrier_async_and_wait_f(self, context, work) }
1347    }
1348}
1349
1350extern "C" {
1351    /// Associates a subsystem-specific context with a dispatch queue, for a key
1352    /// unique to the subsystem.
1353    ///
1354    ///
1355    /// The specified destructor will be invoked with the context on the default
1356    /// priority global concurrent queue when a new context is set for the same key,
1357    /// or after all references to the queue have been released.
1358    ///
1359    ///
1360    /// Parameter `queue`: The dispatch queue to modify.
1361    /// The result of passing NULL in this parameter is undefined.
1362    ///
1363    ///
1364    /// Parameter `key`: The key to set the context for, typically a pointer to a static variable
1365    /// specific to the subsystem. Keys are only compared as pointers and never
1366    /// dereferenced. Passing a string constant directly is not recommended.
1367    /// The NULL key is reserved and attempts to set a context for it are ignored.
1368    ///
1369    ///
1370    /// Parameter `context`: The new subsystem-specific context for the object. This may be NULL.
1371    ///
1372    ///
1373    /// Parameter `destructor`: The destructor function pointer. This may be NULL and is ignored if context
1374    /// is NULL.
1375    pub fn dispatch_queue_set_specific(
1376        queue: &DispatchQueue,
1377        key: NonNull<c_void>,
1378        context: *mut c_void,
1379        destructor: dispatch_function_t,
1380    );
1381}
1382
1383impl DispatchQueue {
1384    /// Returns the subsystem-specific context associated with a dispatch queue, for
1385    /// a key unique to the subsystem.
1386    ///
1387    ///
1388    /// Returns the context for the specified key if it has been set on the specified
1389    /// queue.
1390    ///
1391    ///
1392    /// Parameter `queue`: The dispatch queue to query.
1393    /// The result of passing NULL in this parameter is undefined.
1394    ///
1395    ///
1396    /// Parameter `key`: The key to get the context for, typically a pointer to a static variable
1397    /// specific to the subsystem. Keys are only compared as pointers and never
1398    /// dereferenced. Passing a string constant directly is not recommended.
1399    ///
1400    ///
1401    /// Returns: The context for the specified key or NULL if no context was found.
1402    #[doc(alias = "dispatch_queue_get_specific")]
1403    #[must_use]
1404    #[inline]
1405    pub unsafe fn specific(self: &DispatchQueue, key: NonNull<c_void>) -> *mut c_void {
1406        extern "C" {
1407            fn dispatch_queue_get_specific(
1408                queue: &DispatchQueue,
1409                key: NonNull<c_void>,
1410            ) -> *mut c_void;
1411        }
1412        unsafe { dispatch_queue_get_specific(self, key) }
1413    }
1414}
1415
1416extern "C" {
1417    /// Returns the current subsystem-specific context for a key unique to the
1418    /// subsystem.
1419    ///
1420    ///
1421    /// When called from a block executing on a queue, returns the context for the
1422    /// specified key if it has been set on the queue, otherwise returns the result
1423    /// of dispatch_get_specific() executed on the queue's target queue or NULL
1424    /// if the current queue is a global concurrent queue.
1425    ///
1426    ///
1427    /// Parameter `key`: The key to get the context for, typically a pointer to a static variable
1428    /// specific to the subsystem. Keys are only compared as pointers and never
1429    /// dereferenced. Passing a string constant directly is not recommended.
1430    ///
1431    ///
1432    /// Returns: The context for the specified key or NULL if no context was found.
1433    #[must_use]
1434    pub fn dispatch_get_specific(key: NonNull<c_void>) -> *mut c_void;
1435}
1436
1437impl DispatchQueue {
1438    /// Verifies that the current block is executing on a given dispatch queue.
1439    ///
1440    ///
1441    /// Some code expects to be run on a specific dispatch queue. This function
1442    /// verifies that that expectation is true.
1443    ///
1444    /// If the currently executing block was submitted to the specified queue or to
1445    /// any queue targeting it (see dispatch_set_target_queue()), this function
1446    /// returns.
1447    ///
1448    /// If the currently executing block was submitted with a synchronous API
1449    /// (dispatch_sync(), dispatch_barrier_sync(), ...), the context of the
1450    /// submitting block is also evaluated (recursively).
1451    /// If a synchronously submitting block is found that was itself submitted to
1452    /// the specified queue or to any queue targeting it, this function returns.
1453    ///
1454    /// Otherwise this function asserts: it logs an explanation to the system log and
1455    /// terminates the application.
1456    ///
1457    /// Passing the result of dispatch_get_main_queue() to this function verifies
1458    /// that the current block was submitted to the main queue, or to a queue
1459    /// targeting it, or is running on the main thread (in any context).
1460    ///
1461    /// When dispatch_assert_queue() is called outside of the context of a
1462    /// submitted block (for example from the context of a thread created manually
1463    /// with pthread_create()) then this function will also assert and terminate
1464    /// the application.
1465    ///
1466    /// The variant dispatch_assert_queue_debug() is compiled out when the
1467    /// preprocessor macro NDEBUG is defined. (See also assert(3)).
1468    ///
1469    ///
1470    /// Parameter `queue`: The dispatch queue that the current block is expected to run on.
1471    /// The result of passing NULL in this parameter is undefined.
1472    #[doc(alias = "dispatch_assert_queue")]
1473    #[inline]
1474    pub fn assert(self: &DispatchQueue) {
1475        extern "C-unwind" {
1476            #[cfg_attr(target_vendor = "apple", link_name = "dispatch_assert_queue$V2")]
1477            fn dispatch_assert_queue(queue: &DispatchQueue);
1478        }
1479        unsafe { dispatch_assert_queue(self) }
1480    }
1481
1482    /// Verifies that the current block is executing on a given dispatch queue,
1483    /// and that the block acts as a barrier on that queue.
1484    ///
1485    ///
1486    /// This behaves exactly like dispatch_assert_queue(), with the additional check
1487    /// that the current block acts as a barrier on the specified queue, which is
1488    /// always true if the specified queue is serial (see DISPATCH_BLOCK_BARRIER or
1489    /// dispatch_barrier_async() for details).
1490    ///
1491    /// The variant dispatch_assert_queue_barrier_debug() is compiled out when the
1492    /// preprocessor macro NDEBUG is defined. (See also assert()).
1493    ///
1494    ///
1495    /// Parameter `queue`: The dispatch queue that the current block is expected to run as a barrier on.
1496    /// The result of passing NULL in this parameter is undefined.
1497    #[doc(alias = "dispatch_assert_queue_barrier")]
1498    #[inline]
1499    pub fn assert_barrier(self: &DispatchQueue) {
1500        extern "C-unwind" {
1501            fn dispatch_assert_queue_barrier(queue: &DispatchQueue);
1502        }
1503        unsafe { dispatch_assert_queue_barrier(self) }
1504    }
1505
1506    /// Verifies that the current block is not executing on a given dispatch queue.
1507    ///
1508    ///
1509    /// This function is the equivalent of dispatch_assert_queue() with the test for
1510    /// equality inverted. That means that it will terminate the application when
1511    /// dispatch_assert_queue() would return, and vice-versa. See discussion there.
1512    ///
1513    /// The variant dispatch_assert_queue_not_debug() is compiled out when the
1514    /// preprocessor macro NDEBUG is defined. (See also assert(3)).
1515    ///
1516    ///
1517    /// Parameter `queue`: The dispatch queue that the current block is expected not to run on.
1518    /// The result of passing NULL in this parameter is undefined.
1519    #[doc(alias = "dispatch_assert_queue_not")]
1520    #[inline]
1521    pub fn assert_not(self: &DispatchQueue) {
1522        extern "C-unwind" {
1523            #[cfg_attr(target_vendor = "apple", link_name = "dispatch_assert_queue_not$V2")]
1524            fn dispatch_assert_queue_not(queue: &DispatchQueue);
1525        }
1526        unsafe { dispatch_assert_queue_not(self) }
1527    }
1528}
1529
1530extern "C-unwind" {
1531    pub fn dispatch_allow_send_signals(preserve_signum: c_int) -> c_int;
1532}
1533
1534/// Flags to pass to the dispatch_block_create* functions.
1535///
1536///
1537/// Flag indicating that a dispatch block object should act as a barrier block
1538/// when submitted to a DISPATCH_QUEUE_CONCURRENT queue.
1539/// See dispatch_barrier_async() for details.
1540/// This flag has no effect when the dispatch block object is invoked directly.
1541///
1542///
1543/// Flag indicating that a dispatch block object should execute disassociated
1544/// from current execution context attributes such as os_activity_t
1545/// and properties of the current IPC request (if any). With regard to QoS class,
1546/// the behavior is the same as for DISPATCH_BLOCK_NO_QOS. If invoked directly,
1547/// the block object will remove the other attributes from the calling thread for
1548/// the duration of the block body (before applying attributes assigned to the
1549/// block object, if any). If submitted to a queue, the block object will be
1550/// executed with the attributes of the queue (or any attributes specifically
1551/// assigned to the block object).
1552///
1553///
1554/// Flag indicating that a dispatch block object should be assigned the execution
1555/// context attributes that are current at the time the block object is created.
1556/// This applies to attributes such as QOS class, os_activity_t and properties of
1557/// the current IPC request (if any). If invoked directly, the block object will
1558/// apply these attributes to the calling thread for the duration of the block
1559/// body. If the block object is submitted to a queue, this flag replaces the
1560/// default behavior of associating the submitted block instance with the
1561/// execution context attributes that are current at the time of submission.
1562/// If a specific QOS class is assigned with DISPATCH_BLOCK_NO_QOS_CLASS or
1563/// dispatch_block_create_with_qos_class(), that QOS class takes precedence over
1564/// the QOS class assignment indicated by this flag.
1565///
1566///
1567/// Flag indicating that a dispatch block object should be not be assigned a QOS
1568/// class. If invoked directly, the block object will be executed with the QOS
1569/// class of the calling thread. If the block object is submitted to a queue,
1570/// this replaces the default behavior of associating the submitted block
1571/// instance with the QOS class current at the time of submission.
1572/// This flag is ignored if a specific QOS class is assigned with
1573/// dispatch_block_create_with_qos_class().
1574///
1575///
1576/// Flag indicating that execution of a dispatch block object submitted to a
1577/// queue should prefer the QOS class assigned to the queue over the QOS class
1578/// assigned to the block (resp. associated with the block at the time of
1579/// submission). The latter will only be used if the queue in question does not
1580/// have an assigned QOS class, as long as doing so does not result in a QOS
1581/// class lower than the QOS class inherited from the queue's target queue.
1582/// This flag is the default when a dispatch block object is submitted to a queue
1583/// for asynchronous execution and has no effect when the dispatch block object
1584/// is invoked directly. It is ignored if DISPATCH_BLOCK_ENFORCE_QOS_CLASS is
1585/// also passed.
1586///
1587///
1588/// Flag indicating that execution of a dispatch block object submitted to a
1589/// queue should prefer the QOS class assigned to the block (resp. associated
1590/// with the block at the time of submission) over the QOS class assigned to the
1591/// queue, as long as doing so will not result in a lower QOS class.
1592/// This flag is the default when a dispatch block object is submitted to a queue
1593/// for synchronous execution or when the dispatch block object is invoked
1594/// directly.
1595///
1596/// See also [Apple's documentation](https://developer.apple.com/documentation/dispatch/dispatch_block_flags_t?language=objc)
1597// NS_OPTIONS
1598#[repr(transparent)]
1599#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
1600pub struct dispatch_block_flags_t(pub c_ulong);
1601bitflags::bitflags! {
1602    impl dispatch_block_flags_t: c_ulong {
1603/// Flags to pass to the dispatch_block_create* functions.
1604///
1605///
1606/// Flag indicating that a dispatch block object should act as a barrier block
1607/// when submitted to a DISPATCH_QUEUE_CONCURRENT queue.
1608/// See dispatch_barrier_async() for details.
1609/// This flag has no effect when the dispatch block object is invoked directly.
1610///
1611///
1612/// Flag indicating that a dispatch block object should execute disassociated
1613/// from current execution context attributes such as os_activity_t
1614/// and properties of the current IPC request (if any). With regard to QoS class,
1615/// the behavior is the same as for DISPATCH_BLOCK_NO_QOS. If invoked directly,
1616/// the block object will remove the other attributes from the calling thread for
1617/// the duration of the block body (before applying attributes assigned to the
1618/// block object, if any). If submitted to a queue, the block object will be
1619/// executed with the attributes of the queue (or any attributes specifically
1620/// assigned to the block object).
1621///
1622///
1623/// Flag indicating that a dispatch block object should be assigned the execution
1624/// context attributes that are current at the time the block object is created.
1625/// This applies to attributes such as QOS class, os_activity_t and properties of
1626/// the current IPC request (if any). If invoked directly, the block object will
1627/// apply these attributes to the calling thread for the duration of the block
1628/// body. If the block object is submitted to a queue, this flag replaces the
1629/// default behavior of associating the submitted block instance with the
1630/// execution context attributes that are current at the time of submission.
1631/// If a specific QOS class is assigned with DISPATCH_BLOCK_NO_QOS_CLASS or
1632/// dispatch_block_create_with_qos_class(), that QOS class takes precedence over
1633/// the QOS class assignment indicated by this flag.
1634///
1635///
1636/// Flag indicating that a dispatch block object should be not be assigned a QOS
1637/// class. If invoked directly, the block object will be executed with the QOS
1638/// class of the calling thread. If the block object is submitted to a queue,
1639/// this replaces the default behavior of associating the submitted block
1640/// instance with the QOS class current at the time of submission.
1641/// This flag is ignored if a specific QOS class is assigned with
1642/// dispatch_block_create_with_qos_class().
1643///
1644///
1645/// Flag indicating that execution of a dispatch block object submitted to a
1646/// queue should prefer the QOS class assigned to the queue over the QOS class
1647/// assigned to the block (resp. associated with the block at the time of
1648/// submission). The latter will only be used if the queue in question does not
1649/// have an assigned QOS class, as long as doing so does not result in a QOS
1650/// class lower than the QOS class inherited from the queue's target queue.
1651/// This flag is the default when a dispatch block object is submitted to a queue
1652/// for asynchronous execution and has no effect when the dispatch block object
1653/// is invoked directly. It is ignored if DISPATCH_BLOCK_ENFORCE_QOS_CLASS is
1654/// also passed.
1655///
1656///
1657/// Flag indicating that execution of a dispatch block object submitted to a
1658/// queue should prefer the QOS class assigned to the block (resp. associated
1659/// with the block at the time of submission) over the QOS class assigned to the
1660/// queue, as long as doing so will not result in a lower QOS class.
1661/// This flag is the default when a dispatch block object is submitted to a queue
1662/// for synchronous execution or when the dispatch block object is invoked
1663/// directly.
1664        const DISPATCH_BLOCK_BARRIER = 0x1;
1665/// Flags to pass to the dispatch_block_create* functions.
1666///
1667///
1668/// Flag indicating that a dispatch block object should act as a barrier block
1669/// when submitted to a DISPATCH_QUEUE_CONCURRENT queue.
1670/// See dispatch_barrier_async() for details.
1671/// This flag has no effect when the dispatch block object is invoked directly.
1672///
1673///
1674/// Flag indicating that a dispatch block object should execute disassociated
1675/// from current execution context attributes such as os_activity_t
1676/// and properties of the current IPC request (if any). With regard to QoS class,
1677/// the behavior is the same as for DISPATCH_BLOCK_NO_QOS. If invoked directly,
1678/// the block object will remove the other attributes from the calling thread for
1679/// the duration of the block body (before applying attributes assigned to the
1680/// block object, if any). If submitted to a queue, the block object will be
1681/// executed with the attributes of the queue (or any attributes specifically
1682/// assigned to the block object).
1683///
1684///
1685/// Flag indicating that a dispatch block object should be assigned the execution
1686/// context attributes that are current at the time the block object is created.
1687/// This applies to attributes such as QOS class, os_activity_t and properties of
1688/// the current IPC request (if any). If invoked directly, the block object will
1689/// apply these attributes to the calling thread for the duration of the block
1690/// body. If the block object is submitted to a queue, this flag replaces the
1691/// default behavior of associating the submitted block instance with the
1692/// execution context attributes that are current at the time of submission.
1693/// If a specific QOS class is assigned with DISPATCH_BLOCK_NO_QOS_CLASS or
1694/// dispatch_block_create_with_qos_class(), that QOS class takes precedence over
1695/// the QOS class assignment indicated by this flag.
1696///
1697///
1698/// Flag indicating that a dispatch block object should be not be assigned a QOS
1699/// class. If invoked directly, the block object will be executed with the QOS
1700/// class of the calling thread. If the block object is submitted to a queue,
1701/// this replaces the default behavior of associating the submitted block
1702/// instance with the QOS class current at the time of submission.
1703/// This flag is ignored if a specific QOS class is assigned with
1704/// dispatch_block_create_with_qos_class().
1705///
1706///
1707/// Flag indicating that execution of a dispatch block object submitted to a
1708/// queue should prefer the QOS class assigned to the queue over the QOS class
1709/// assigned to the block (resp. associated with the block at the time of
1710/// submission). The latter will only be used if the queue in question does not
1711/// have an assigned QOS class, as long as doing so does not result in a QOS
1712/// class lower than the QOS class inherited from the queue's target queue.
1713/// This flag is the default when a dispatch block object is submitted to a queue
1714/// for asynchronous execution and has no effect when the dispatch block object
1715/// is invoked directly. It is ignored if DISPATCH_BLOCK_ENFORCE_QOS_CLASS is
1716/// also passed.
1717///
1718///
1719/// Flag indicating that execution of a dispatch block object submitted to a
1720/// queue should prefer the QOS class assigned to the block (resp. associated
1721/// with the block at the time of submission) over the QOS class assigned to the
1722/// queue, as long as doing so will not result in a lower QOS class.
1723/// This flag is the default when a dispatch block object is submitted to a queue
1724/// for synchronous execution or when the dispatch block object is invoked
1725/// directly.
1726        const DISPATCH_BLOCK_DETACHED = 0x2;
1727/// Flags to pass to the dispatch_block_create* functions.
1728///
1729///
1730/// Flag indicating that a dispatch block object should act as a barrier block
1731/// when submitted to a DISPATCH_QUEUE_CONCURRENT queue.
1732/// See dispatch_barrier_async() for details.
1733/// This flag has no effect when the dispatch block object is invoked directly.
1734///
1735///
1736/// Flag indicating that a dispatch block object should execute disassociated
1737/// from current execution context attributes such as os_activity_t
1738/// and properties of the current IPC request (if any). With regard to QoS class,
1739/// the behavior is the same as for DISPATCH_BLOCK_NO_QOS. If invoked directly,
1740/// the block object will remove the other attributes from the calling thread for
1741/// the duration of the block body (before applying attributes assigned to the
1742/// block object, if any). If submitted to a queue, the block object will be
1743/// executed with the attributes of the queue (or any attributes specifically
1744/// assigned to the block object).
1745///
1746///
1747/// Flag indicating that a dispatch block object should be assigned the execution
1748/// context attributes that are current at the time the block object is created.
1749/// This applies to attributes such as QOS class, os_activity_t and properties of
1750/// the current IPC request (if any). If invoked directly, the block object will
1751/// apply these attributes to the calling thread for the duration of the block
1752/// body. If the block object is submitted to a queue, this flag replaces the
1753/// default behavior of associating the submitted block instance with the
1754/// execution context attributes that are current at the time of submission.
1755/// If a specific QOS class is assigned with DISPATCH_BLOCK_NO_QOS_CLASS or
1756/// dispatch_block_create_with_qos_class(), that QOS class takes precedence over
1757/// the QOS class assignment indicated by this flag.
1758///
1759///
1760/// Flag indicating that a dispatch block object should be not be assigned a QOS
1761/// class. If invoked directly, the block object will be executed with the QOS
1762/// class of the calling thread. If the block object is submitted to a queue,
1763/// this replaces the default behavior of associating the submitted block
1764/// instance with the QOS class current at the time of submission.
1765/// This flag is ignored if a specific QOS class is assigned with
1766/// dispatch_block_create_with_qos_class().
1767///
1768///
1769/// Flag indicating that execution of a dispatch block object submitted to a
1770/// queue should prefer the QOS class assigned to the queue over the QOS class
1771/// assigned to the block (resp. associated with the block at the time of
1772/// submission). The latter will only be used if the queue in question does not
1773/// have an assigned QOS class, as long as doing so does not result in a QOS
1774/// class lower than the QOS class inherited from the queue's target queue.
1775/// This flag is the default when a dispatch block object is submitted to a queue
1776/// for asynchronous execution and has no effect when the dispatch block object
1777/// is invoked directly. It is ignored if DISPATCH_BLOCK_ENFORCE_QOS_CLASS is
1778/// also passed.
1779///
1780///
1781/// Flag indicating that execution of a dispatch block object submitted to a
1782/// queue should prefer the QOS class assigned to the block (resp. associated
1783/// with the block at the time of submission) over the QOS class assigned to the
1784/// queue, as long as doing so will not result in a lower QOS class.
1785/// This flag is the default when a dispatch block object is submitted to a queue
1786/// for synchronous execution or when the dispatch block object is invoked
1787/// directly.
1788        const DISPATCH_BLOCK_ASSIGN_CURRENT = 0x4;
1789/// Flags to pass to the dispatch_block_create* functions.
1790///
1791///
1792/// Flag indicating that a dispatch block object should act as a barrier block
1793/// when submitted to a DISPATCH_QUEUE_CONCURRENT queue.
1794/// See dispatch_barrier_async() for details.
1795/// This flag has no effect when the dispatch block object is invoked directly.
1796///
1797///
1798/// Flag indicating that a dispatch block object should execute disassociated
1799/// from current execution context attributes such as os_activity_t
1800/// and properties of the current IPC request (if any). With regard to QoS class,
1801/// the behavior is the same as for DISPATCH_BLOCK_NO_QOS. If invoked directly,
1802/// the block object will remove the other attributes from the calling thread for
1803/// the duration of the block body (before applying attributes assigned to the
1804/// block object, if any). If submitted to a queue, the block object will be
1805/// executed with the attributes of the queue (or any attributes specifically
1806/// assigned to the block object).
1807///
1808///
1809/// Flag indicating that a dispatch block object should be assigned the execution
1810/// context attributes that are current at the time the block object is created.
1811/// This applies to attributes such as QOS class, os_activity_t and properties of
1812/// the current IPC request (if any). If invoked directly, the block object will
1813/// apply these attributes to the calling thread for the duration of the block
1814/// body. If the block object is submitted to a queue, this flag replaces the
1815/// default behavior of associating the submitted block instance with the
1816/// execution context attributes that are current at the time of submission.
1817/// If a specific QOS class is assigned with DISPATCH_BLOCK_NO_QOS_CLASS or
1818/// dispatch_block_create_with_qos_class(), that QOS class takes precedence over
1819/// the QOS class assignment indicated by this flag.
1820///
1821///
1822/// Flag indicating that a dispatch block object should be not be assigned a QOS
1823/// class. If invoked directly, the block object will be executed with the QOS
1824/// class of the calling thread. If the block object is submitted to a queue,
1825/// this replaces the default behavior of associating the submitted block
1826/// instance with the QOS class current at the time of submission.
1827/// This flag is ignored if a specific QOS class is assigned with
1828/// dispatch_block_create_with_qos_class().
1829///
1830///
1831/// Flag indicating that execution of a dispatch block object submitted to a
1832/// queue should prefer the QOS class assigned to the queue over the QOS class
1833/// assigned to the block (resp. associated with the block at the time of
1834/// submission). The latter will only be used if the queue in question does not
1835/// have an assigned QOS class, as long as doing so does not result in a QOS
1836/// class lower than the QOS class inherited from the queue's target queue.
1837/// This flag is the default when a dispatch block object is submitted to a queue
1838/// for asynchronous execution and has no effect when the dispatch block object
1839/// is invoked directly. It is ignored if DISPATCH_BLOCK_ENFORCE_QOS_CLASS is
1840/// also passed.
1841///
1842///
1843/// Flag indicating that execution of a dispatch block object submitted to a
1844/// queue should prefer the QOS class assigned to the block (resp. associated
1845/// with the block at the time of submission) over the QOS class assigned to the
1846/// queue, as long as doing so will not result in a lower QOS class.
1847/// This flag is the default when a dispatch block object is submitted to a queue
1848/// for synchronous execution or when the dispatch block object is invoked
1849/// directly.
1850        const DISPATCH_BLOCK_NO_QOS_CLASS = 0x8;
1851/// Flags to pass to the dispatch_block_create* functions.
1852///
1853///
1854/// Flag indicating that a dispatch block object should act as a barrier block
1855/// when submitted to a DISPATCH_QUEUE_CONCURRENT queue.
1856/// See dispatch_barrier_async() for details.
1857/// This flag has no effect when the dispatch block object is invoked directly.
1858///
1859///
1860/// Flag indicating that a dispatch block object should execute disassociated
1861/// from current execution context attributes such as os_activity_t
1862/// and properties of the current IPC request (if any). With regard to QoS class,
1863/// the behavior is the same as for DISPATCH_BLOCK_NO_QOS. If invoked directly,
1864/// the block object will remove the other attributes from the calling thread for
1865/// the duration of the block body (before applying attributes assigned to the
1866/// block object, if any). If submitted to a queue, the block object will be
1867/// executed with the attributes of the queue (or any attributes specifically
1868/// assigned to the block object).
1869///
1870///
1871/// Flag indicating that a dispatch block object should be assigned the execution
1872/// context attributes that are current at the time the block object is created.
1873/// This applies to attributes such as QOS class, os_activity_t and properties of
1874/// the current IPC request (if any). If invoked directly, the block object will
1875/// apply these attributes to the calling thread for the duration of the block
1876/// body. If the block object is submitted to a queue, this flag replaces the
1877/// default behavior of associating the submitted block instance with the
1878/// execution context attributes that are current at the time of submission.
1879/// If a specific QOS class is assigned with DISPATCH_BLOCK_NO_QOS_CLASS or
1880/// dispatch_block_create_with_qos_class(), that QOS class takes precedence over
1881/// the QOS class assignment indicated by this flag.
1882///
1883///
1884/// Flag indicating that a dispatch block object should be not be assigned a QOS
1885/// class. If invoked directly, the block object will be executed with the QOS
1886/// class of the calling thread. If the block object is submitted to a queue,
1887/// this replaces the default behavior of associating the submitted block
1888/// instance with the QOS class current at the time of submission.
1889/// This flag is ignored if a specific QOS class is assigned with
1890/// dispatch_block_create_with_qos_class().
1891///
1892///
1893/// Flag indicating that execution of a dispatch block object submitted to a
1894/// queue should prefer the QOS class assigned to the queue over the QOS class
1895/// assigned to the block (resp. associated with the block at the time of
1896/// submission). The latter will only be used if the queue in question does not
1897/// have an assigned QOS class, as long as doing so does not result in a QOS
1898/// class lower than the QOS class inherited from the queue's target queue.
1899/// This flag is the default when a dispatch block object is submitted to a queue
1900/// for asynchronous execution and has no effect when the dispatch block object
1901/// is invoked directly. It is ignored if DISPATCH_BLOCK_ENFORCE_QOS_CLASS is
1902/// also passed.
1903///
1904///
1905/// Flag indicating that execution of a dispatch block object submitted to a
1906/// queue should prefer the QOS class assigned to the block (resp. associated
1907/// with the block at the time of submission) over the QOS class assigned to the
1908/// queue, as long as doing so will not result in a lower QOS class.
1909/// This flag is the default when a dispatch block object is submitted to a queue
1910/// for synchronous execution or when the dispatch block object is invoked
1911/// directly.
1912        const DISPATCH_BLOCK_INHERIT_QOS_CLASS = 0x10;
1913/// Flags to pass to the dispatch_block_create* functions.
1914///
1915///
1916/// Flag indicating that a dispatch block object should act as a barrier block
1917/// when submitted to a DISPATCH_QUEUE_CONCURRENT queue.
1918/// See dispatch_barrier_async() for details.
1919/// This flag has no effect when the dispatch block object is invoked directly.
1920///
1921///
1922/// Flag indicating that a dispatch block object should execute disassociated
1923/// from current execution context attributes such as os_activity_t
1924/// and properties of the current IPC request (if any). With regard to QoS class,
1925/// the behavior is the same as for DISPATCH_BLOCK_NO_QOS. If invoked directly,
1926/// the block object will remove the other attributes from the calling thread for
1927/// the duration of the block body (before applying attributes assigned to the
1928/// block object, if any). If submitted to a queue, the block object will be
1929/// executed with the attributes of the queue (or any attributes specifically
1930/// assigned to the block object).
1931///
1932///
1933/// Flag indicating that a dispatch block object should be assigned the execution
1934/// context attributes that are current at the time the block object is created.
1935/// This applies to attributes such as QOS class, os_activity_t and properties of
1936/// the current IPC request (if any). If invoked directly, the block object will
1937/// apply these attributes to the calling thread for the duration of the block
1938/// body. If the block object is submitted to a queue, this flag replaces the
1939/// default behavior of associating the submitted block instance with the
1940/// execution context attributes that are current at the time of submission.
1941/// If a specific QOS class is assigned with DISPATCH_BLOCK_NO_QOS_CLASS or
1942/// dispatch_block_create_with_qos_class(), that QOS class takes precedence over
1943/// the QOS class assignment indicated by this flag.
1944///
1945///
1946/// Flag indicating that a dispatch block object should be not be assigned a QOS
1947/// class. If invoked directly, the block object will be executed with the QOS
1948/// class of the calling thread. If the block object is submitted to a queue,
1949/// this replaces the default behavior of associating the submitted block
1950/// instance with the QOS class current at the time of submission.
1951/// This flag is ignored if a specific QOS class is assigned with
1952/// dispatch_block_create_with_qos_class().
1953///
1954///
1955/// Flag indicating that execution of a dispatch block object submitted to a
1956/// queue should prefer the QOS class assigned to the queue over the QOS class
1957/// assigned to the block (resp. associated with the block at the time of
1958/// submission). The latter will only be used if the queue in question does not
1959/// have an assigned QOS class, as long as doing so does not result in a QOS
1960/// class lower than the QOS class inherited from the queue's target queue.
1961/// This flag is the default when a dispatch block object is submitted to a queue
1962/// for asynchronous execution and has no effect when the dispatch block object
1963/// is invoked directly. It is ignored if DISPATCH_BLOCK_ENFORCE_QOS_CLASS is
1964/// also passed.
1965///
1966///
1967/// Flag indicating that execution of a dispatch block object submitted to a
1968/// queue should prefer the QOS class assigned to the block (resp. associated
1969/// with the block at the time of submission) over the QOS class assigned to the
1970/// queue, as long as doing so will not result in a lower QOS class.
1971/// This flag is the default when a dispatch block object is submitted to a queue
1972/// for synchronous execution or when the dispatch block object is invoked
1973/// directly.
1974        const DISPATCH_BLOCK_ENFORCE_QOS_CLASS = 0x20;
1975    }
1976}
1977
1978#[cfg(feature = "objc2")]
1979unsafe impl Encode for dispatch_block_flags_t {
1980    const ENCODING: Encoding = Encoding::C_ULONG;
1981}
1982
1983#[cfg(feature = "objc2")]
1984unsafe impl RefEncode for dispatch_block_flags_t {
1985    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
1986}
1987
1988extern "C" {
1989    /// Create a new dispatch block object on the heap from an existing block and
1990    /// the given flags.
1991    ///
1992    ///
1993    /// The provided block is Block_copy'ed to the heap and retained by the newly
1994    /// created dispatch block object.
1995    ///
1996    /// The returned dispatch block object is intended to be submitted to a dispatch
1997    /// queue with dispatch_async() and related functions, but may also be invoked
1998    /// directly. Both operations can be performed an arbitrary number of times but
1999    /// only the first completed execution of a dispatch block object can be waited
2000    /// on with dispatch_block_wait() or observed with dispatch_block_notify().
2001    ///
2002    /// If the returned dispatch block object is submitted to a dispatch queue, the
2003    /// submitted block instance will be associated with the QOS class current at the
2004    /// time of submission, unless one of the following flags assigned a specific QOS
2005    /// class (or no QOS class) at the time of block creation:
2006    /// - DISPATCH_BLOCK_ASSIGN_CURRENT
2007    /// - DISPATCH_BLOCK_NO_QOS_CLASS
2008    /// - DISPATCH_BLOCK_DETACHED
2009    /// The QOS class the block object will be executed with also depends on the QOS
2010    /// class assigned to the queue and which of the following flags was specified or
2011    /// defaulted to:
2012    /// - DISPATCH_BLOCK_INHERIT_QOS_CLASS (default for asynchronous execution)
2013    /// - DISPATCH_BLOCK_ENFORCE_QOS_CLASS (default for synchronous execution)
2014    /// See description of dispatch_block_flags_t for details.
2015    ///
2016    /// If the returned dispatch block object is submitted directly to a serial queue
2017    /// and is configured to execute with a specific QOS class, the system will make
2018    /// a best effort to apply the necessary QOS overrides to ensure that blocks
2019    /// submitted earlier to the serial queue are executed at that same QOS class or
2020    /// higher.
2021    ///
2022    ///
2023    /// Parameter `flags`: Configuration flags for the block object.
2024    /// Passing a value that is not a bitwise OR of flags from dispatch_block_flags_t
2025    /// results in NULL being returned.
2026    ///
2027    ///
2028    /// Parameter `block`: The block to create the dispatch block object from.
2029    ///
2030    ///
2031    /// Returns: The newly created dispatch block object, or NULL.
2032    /// When not building with Objective-C ARC, must be released with a -[release]
2033    /// message or the Block_release() function.
2034    #[cfg(feature = "block2")]
2035    #[must_use]
2036    pub fn dispatch_block_create(
2037        flags: dispatch_block_flags_t,
2038        block: dispatch_block_t,
2039    ) -> dispatch_block_t;
2040}
2041
2042extern "C" {
2043    /// Create a new dispatch block object on the heap from an existing block and
2044    /// the given flags, and assign it the specified QOS class and relative priority.
2045    ///
2046    ///
2047    /// The provided block is Block_copy'ed to the heap and retained by the newly
2048    /// created dispatch block object.
2049    ///
2050    /// The returned dispatch block object is intended to be submitted to a dispatch
2051    /// queue with dispatch_async() and related functions, but may also be invoked
2052    /// directly. Both operations can be performed an arbitrary number of times but
2053    /// only the first completed execution of a dispatch block object can be waited
2054    /// on with dispatch_block_wait() or observed with dispatch_block_notify().
2055    ///
2056    /// If invoked directly, the returned dispatch block object will be executed with
2057    /// the assigned QOS class as long as that does not result in a lower QOS class
2058    /// than what is current on the calling thread.
2059    ///
2060    /// If the returned dispatch block object is submitted to a dispatch queue, the
2061    /// QOS class it will be executed with depends on the QOS class assigned to the
2062    /// block, the QOS class assigned to the queue and which of the following flags
2063    /// was specified or defaulted to:
2064    /// - DISPATCH_BLOCK_INHERIT_QOS_CLASS: default for asynchronous execution
2065    /// - DISPATCH_BLOCK_ENFORCE_QOS_CLASS: default for synchronous execution
2066    /// See description of dispatch_block_flags_t for details.
2067    ///
2068    /// If the returned dispatch block object is submitted directly to a serial queue
2069    /// and is configured to execute with a specific QOS class, the system will make
2070    /// a best effort to apply the necessary QOS overrides to ensure that blocks
2071    /// submitted earlier to the serial queue are executed at that same QOS class or
2072    /// higher.
2073    ///
2074    ///
2075    /// Parameter `flags`: Configuration flags for the new block object.
2076    /// Passing a value that is not a bitwise OR of flags from dispatch_block_flags_t
2077    /// results in NULL being returned.
2078    ///
2079    ///
2080    /// Parameter `qos_class`: A QOS class value:
2081    /// - QOS_CLASS_USER_INTERACTIVE
2082    /// - QOS_CLASS_USER_INITIATED
2083    /// - QOS_CLASS_DEFAULT
2084    /// - QOS_CLASS_UTILITY
2085    /// - QOS_CLASS_BACKGROUND
2086    /// - QOS_CLASS_UNSPECIFIED
2087    /// Passing QOS_CLASS_UNSPECIFIED is equivalent to specifying the
2088    /// DISPATCH_BLOCK_NO_QOS_CLASS flag. Passing any other value results in NULL
2089    /// being returned.
2090    ///
2091    ///
2092    /// Parameter `relative_priority`: A relative priority within the QOS class. This value is a negative
2093    /// offset from the maximum supported scheduler priority for the given class.
2094    /// Passing a value greater than zero or less than QOS_MIN_RELATIVE_PRIORITY
2095    /// results in NULL being returned.
2096    ///
2097    ///
2098    /// Parameter `block`: The block to create the dispatch block object from.
2099    ///
2100    ///
2101    /// Returns: The newly created dispatch block object, or NULL.
2102    /// When not building with Objective-C ARC, must be released with a -[release]
2103    /// message or the Block_release() function.
2104    #[cfg(feature = "block2")]
2105    #[must_use]
2106    pub fn dispatch_block_create_with_qos_class(
2107        flags: dispatch_block_flags_t,
2108        qos_class: DispatchQoS,
2109        relative_priority: c_int,
2110        block: dispatch_block_t,
2111    ) -> dispatch_block_t;
2112}
2113
2114extern "C" {
2115    /// Create, synchronously execute and release a dispatch block object from the
2116    /// specified block and flags.
2117    ///
2118    ///
2119    /// Behaves identically to the sequence
2120    /// <code>
2121    /// dispatch_block_t b = dispatch_block_create(flags, block);
2122    /// b();
2123    /// Block_release(b);
2124    /// </code>
2125    /// but may be implemented more efficiently internally by not requiring a copy
2126    /// to the heap of the specified block or the allocation of a new block object.
2127    ///
2128    ///
2129    /// Parameter `flags`: Configuration flags for the temporary block object.
2130    /// The result of passing a value that is not a bitwise OR of flags from
2131    /// dispatch_block_flags_t is undefined.
2132    ///
2133    ///
2134    /// Parameter `block`: The block to create the temporary block object from.
2135    #[cfg(feature = "block2")]
2136    pub fn dispatch_block_perform(flags: dispatch_block_flags_t, block: dispatch_block_t);
2137}
2138
2139extern "C" {
2140    /// Wait synchronously until execution of the specified dispatch block object has
2141    /// completed or until the specified timeout has elapsed.
2142    ///
2143    ///
2144    /// This function will return immediately if execution of the block object has
2145    /// already completed.
2146    ///
2147    /// It is not possible to wait for multiple executions of the same block object
2148    /// with this interface; use dispatch_group_wait() for that purpose. A single
2149    /// dispatch block object may either be waited on once and executed once,
2150    /// or it may be executed any number of times. The behavior of any other
2151    /// combination is undefined. Submission to a dispatch queue counts as an
2152    /// execution, even if cancellation (dispatch_block_cancel) means the block's
2153    /// code never runs.
2154    ///
2155    /// The result of calling this function from multiple threads simultaneously
2156    /// with the same dispatch block object is undefined, but note that doing so
2157    /// would violate the rules described in the previous paragraph.
2158    ///
2159    /// If this function returns indicating that the specified timeout has elapsed,
2160    /// then that invocation does not count as the one allowed wait.
2161    ///
2162    /// If at the time this function is called, the specified dispatch block object
2163    /// has been submitted directly to a serial queue, the system will make a best
2164    /// effort to apply the necessary QOS overrides to ensure that the block and any
2165    /// blocks submitted earlier to that serial queue are executed at the QOS class
2166    /// (or higher) of the thread calling dispatch_block_wait().
2167    ///
2168    ///
2169    /// Parameter `block`: The dispatch block object to wait on.
2170    /// The result of passing NULL or a block object not returned by one of the
2171    /// dispatch_block_create* functions is undefined.
2172    ///
2173    ///
2174    /// Parameter `timeout`: When to timeout (see dispatch_time). As a convenience, there are the
2175    /// DISPATCH_TIME_NOW and DISPATCH_TIME_FOREVER constants.
2176    ///
2177    ///
2178    /// Returns: Returns zero on success (the dispatch block object completed within the
2179    /// specified timeout) or non-zero on error (i.e. timed out).
2180    #[cfg(feature = "block2")]
2181    pub fn dispatch_block_wait(block: dispatch_block_t, timeout: DispatchTime) -> isize;
2182}
2183
2184extern "C" {
2185    /// Schedule a notification block to be submitted to a queue when the execution
2186    /// of a specified dispatch block object has completed.
2187    ///
2188    ///
2189    /// This function will submit the notification block immediately if execution of
2190    /// the observed block object has already completed.
2191    ///
2192    /// It is not possible to be notified of multiple executions of the same block
2193    /// object with this interface, use dispatch_group_notify() for that purpose.
2194    ///
2195    /// A single dispatch block object may either be observed one or more times
2196    /// and executed once, or it may be executed any number of times. The behavior
2197    /// of any other combination is undefined. Submission to a dispatch queue
2198    /// counts as an execution, even if cancellation (dispatch_block_cancel) means
2199    /// the block's code never runs.
2200    ///
2201    /// If multiple notification blocks are scheduled for a single block object,
2202    /// there is no defined order in which the notification blocks will be submitted
2203    /// to their associated queues.
2204    ///
2205    ///
2206    /// Parameter `block`: The dispatch block object to observe.
2207    /// The result of passing NULL or a block object not returned by one of the
2208    /// dispatch_block_create* functions is undefined.
2209    ///
2210    ///
2211    /// Parameter `queue`: The queue to which the supplied notification block will be submitted when
2212    /// the observed block completes.
2213    ///
2214    ///
2215    /// Parameter `notification_block`: The notification block to submit when the observed block object completes.
2216    #[cfg(feature = "block2")]
2217    pub fn dispatch_block_notify(
2218        block: dispatch_block_t,
2219        queue: &DispatchQueue,
2220        notification_block: dispatch_block_t,
2221    );
2222}
2223
2224extern "C" {
2225    /// Asynchronously cancel the specified dispatch block object.
2226    ///
2227    ///
2228    /// Cancellation causes any future execution of the dispatch block object to
2229    /// return immediately, but does not affect any execution of the block object
2230    /// that is already in progress.
2231    ///
2232    /// Release of any resources associated with the block object will be delayed
2233    /// until execution of the block object is next attempted (or any execution
2234    /// already in progress completes).
2235    ///
2236    /// NOTE: care needs to be taken to ensure that a block object that may be
2237    /// canceled does not capture any resources that require execution of the
2238    /// block body in order to be released (e.g. memory allocated with
2239    /// malloc(3) that the block body calls free(3) on). Such resources will
2240    /// be leaked if the block body is never executed due to cancellation.
2241    ///
2242    ///
2243    /// Parameter `block`: The dispatch block object to cancel.
2244    /// The result of passing NULL or a block object not returned by one of the
2245    /// dispatch_block_create* functions is undefined.
2246    #[cfg(feature = "block2")]
2247    pub fn dispatch_block_cancel(block: dispatch_block_t);
2248}
2249
2250extern "C" {
2251    /// Tests whether the given dispatch block object has been canceled.
2252    ///
2253    ///
2254    /// Parameter `block`: The dispatch block object to test.
2255    /// The result of passing NULL or a block object not returned by one of the
2256    /// dispatch_block_create* functions is undefined.
2257    ///
2258    ///
2259    /// Returns: Non-zero if canceled and zero if not canceled.
2260    #[cfg(feature = "block2")]
2261    #[must_use]
2262    pub fn dispatch_block_testcancel(block: dispatch_block_t) -> isize;
2263}
2264
2265extern "C" {
2266    /// [Apple's documentation](https://developer.apple.com/documentation/dispatch/_dispatch_source_type_data_add?language=objc)
2267    pub static _dispatch_source_type_data_add: dispatch_source_type_s;
2268}
2269
2270extern "C" {
2271    /// [Apple's documentation](https://developer.apple.com/documentation/dispatch/_dispatch_source_type_data_or?language=objc)
2272    pub static _dispatch_source_type_data_or: dispatch_source_type_s;
2273}
2274
2275extern "C" {
2276    /// [Apple's documentation](https://developer.apple.com/documentation/dispatch/_dispatch_source_type_data_replace?language=objc)
2277    pub static _dispatch_source_type_data_replace: dispatch_source_type_s;
2278}
2279
2280extern "C" {
2281    /// [Apple's documentation](https://developer.apple.com/documentation/dispatch/_dispatch_source_type_mach_send?language=objc)
2282    pub static _dispatch_source_type_mach_send: dispatch_source_type_s;
2283}
2284
2285extern "C" {
2286    /// [Apple's documentation](https://developer.apple.com/documentation/dispatch/_dispatch_source_type_mach_recv?language=objc)
2287    pub static _dispatch_source_type_mach_recv: dispatch_source_type_s;
2288}
2289
2290extern "C" {
2291    /// [Apple's documentation](https://developer.apple.com/documentation/dispatch/_dispatch_source_type_memorypressure?language=objc)
2292    pub static _dispatch_source_type_memorypressure: dispatch_source_type_s;
2293}
2294
2295extern "C" {
2296    /// [Apple's documentation](https://developer.apple.com/documentation/dispatch/_dispatch_source_type_proc?language=objc)
2297    pub static _dispatch_source_type_proc: dispatch_source_type_s;
2298}
2299
2300extern "C" {
2301    /// [Apple's documentation](https://developer.apple.com/documentation/dispatch/_dispatch_source_type_read?language=objc)
2302    pub static _dispatch_source_type_read: dispatch_source_type_s;
2303}
2304
2305extern "C" {
2306    /// [Apple's documentation](https://developer.apple.com/documentation/dispatch/_dispatch_source_type_signal?language=objc)
2307    pub static _dispatch_source_type_signal: dispatch_source_type_s;
2308}
2309
2310extern "C" {
2311    /// [Apple's documentation](https://developer.apple.com/documentation/dispatch/_dispatch_source_type_timer?language=objc)
2312    pub static _dispatch_source_type_timer: dispatch_source_type_s;
2313}
2314
2315extern "C" {
2316    /// [Apple's documentation](https://developer.apple.com/documentation/dispatch/_dispatch_source_type_vnode?language=objc)
2317    pub static _dispatch_source_type_vnode: dispatch_source_type_s;
2318}
2319
2320extern "C" {
2321    /// [Apple's documentation](https://developer.apple.com/documentation/dispatch/_dispatch_source_type_write?language=objc)
2322    pub static _dispatch_source_type_write: dispatch_source_type_s;
2323}
2324
2325impl DispatchSource {
2326    /// Creates a new dispatch source to monitor low-level system objects and auto-
2327    /// matically submit a handler block to a dispatch queue in response to events.
2328    ///
2329    ///
2330    /// Dispatch sources are not reentrant. Any events received while the dispatch
2331    /// source is suspended or while the event handler block is currently executing
2332    /// will be coalesced and delivered after the dispatch source is resumed or the
2333    /// event handler block has returned.
2334    ///
2335    /// Dispatch sources are created in an inactive state. After creating the
2336    /// source and setting any desired attributes (i.e. the handler, context, etc.),
2337    /// a call must be made to dispatch_activate() in order to begin event delivery.
2338    ///
2339    /// A source must have been activated before being disposed.
2340    ///
2341    /// Calling dispatch_set_target_queue() on a source once it has been activated
2342    /// is not allowed (see dispatch_activate() and dispatch_set_target_queue()).
2343    ///
2344    /// For backward compatibility reasons, dispatch_resume() on an inactive,
2345    /// and not otherwise suspended source has the same effect as calling
2346    /// dispatch_activate(). For new code, using dispatch_activate() is preferred.
2347    ///
2348    ///
2349    /// Parameter `type`: Declares the type of the dispatch source. Must be one of the defined
2350    /// dispatch_source_type_t constants.
2351    ///
2352    ///
2353    /// Parameter `handle`: The underlying system handle to monitor. The interpretation of this argument
2354    /// is determined by the constant provided in the type parameter.
2355    ///
2356    ///
2357    /// Parameter `mask`: A mask of flags specifying which events are desired. The interpretation of
2358    /// this argument is determined by the constant provided in the type parameter.
2359    ///
2360    ///
2361    /// Parameter `queue`: The dispatch queue to which the event handler block will be submitted.
2362    /// If queue is DISPATCH_TARGET_QUEUE_DEFAULT, the source will submit the event
2363    /// handler block to the default priority global queue.
2364    ///
2365    ///
2366    /// Returns: The newly created dispatch source. Or NULL if invalid arguments are passed.
2367    #[doc(alias = "dispatch_source_create")]
2368    #[must_use]
2369    #[inline]
2370    pub unsafe fn new(
2371        r#type: dispatch_source_type_t,
2372        handle: usize,
2373        mask: usize,
2374        queue: Option<&DispatchQueue>,
2375    ) -> DispatchRetained<DispatchSource> {
2376        extern "C" {
2377            fn dispatch_source_create(
2378                r#type: dispatch_source_type_t,
2379                handle: usize,
2380                mask: usize,
2381                queue: Option<&DispatchQueue>,
2382            ) -> Option<NonNull<DispatchSource>>;
2383        }
2384        let ret = unsafe { dispatch_source_create(r#type, handle, mask, queue) };
2385        let ret =
2386            ret.expect("function was marked as returning non-null, but actually returned NULL");
2387        unsafe { DispatchRetained::from_raw(ret) }
2388    }
2389
2390    #[doc(alias = "dispatch_source_set_event_handler")]
2391    #[cfg(feature = "block2")]
2392    #[inline]
2393    pub unsafe fn set_event_handler_with_block(self: &DispatchSource, handler: dispatch_block_t) {
2394        extern "C" {
2395            fn dispatch_source_set_event_handler(
2396                source: &DispatchSource,
2397                handler: dispatch_block_t,
2398            );
2399        }
2400        unsafe { dispatch_source_set_event_handler(self, handler) }
2401    }
2402
2403    /// Sets the event handler function for the given dispatch source.
2404    ///
2405    ///
2406    /// Parameter `source`: The dispatch source to modify.
2407    /// The result of passing NULL in this parameter is undefined.
2408    ///
2409    ///
2410    /// Parameter `handler`: The event handler function to submit to the source's target queue.
2411    /// The context parameter passed to the event handler function is the context of
2412    /// the dispatch source current at the time the event handler was set.
2413    #[doc(alias = "dispatch_source_set_event_handler_f")]
2414    #[inline]
2415    pub fn set_event_handler_f(self: &DispatchSource, handler: dispatch_function_t) {
2416        extern "C" {
2417            fn dispatch_source_set_event_handler_f(
2418                source: &DispatchSource,
2419                handler: dispatch_function_t,
2420            );
2421        }
2422        unsafe { dispatch_source_set_event_handler_f(self, handler) }
2423    }
2424
2425    #[doc(alias = "dispatch_source_set_cancel_handler")]
2426    #[cfg(feature = "block2")]
2427    #[inline]
2428    pub unsafe fn set_cancel_handler_with_block(self: &DispatchSource, handler: dispatch_block_t) {
2429        extern "C" {
2430            fn dispatch_source_set_cancel_handler(
2431                source: &DispatchSource,
2432                handler: dispatch_block_t,
2433            );
2434        }
2435        unsafe { dispatch_source_set_cancel_handler(self, handler) }
2436    }
2437
2438    /// Sets the cancellation handler function for the given dispatch source.
2439    ///
2440    ///
2441    /// See dispatch_source_set_cancel_handler() for more details.
2442    ///
2443    ///
2444    /// Parameter `source`: The dispatch source to modify.
2445    /// The result of passing NULL in this parameter is undefined.
2446    ///
2447    ///
2448    /// Parameter `handler`: The cancellation handler function to submit to the source's target queue.
2449    /// The context parameter passed to the event handler function is the current
2450    /// context of the dispatch source at the time the handler call is made.
2451    #[doc(alias = "dispatch_source_set_cancel_handler_f")]
2452    #[inline]
2453    pub fn set_cancel_handler_f(self: &DispatchSource, handler: dispatch_function_t) {
2454        extern "C" {
2455            fn dispatch_source_set_cancel_handler_f(
2456                source: &DispatchSource,
2457                handler: dispatch_function_t,
2458            );
2459        }
2460        unsafe { dispatch_source_set_cancel_handler_f(self, handler) }
2461    }
2462
2463    /// Asynchronously cancel the dispatch source, preventing any further invocation
2464    /// of its event handler block.
2465    ///
2466    ///
2467    /// Cancellation prevents any further invocation of the event handler block for
2468    /// the specified dispatch source, but does not interrupt an event handler
2469    /// block that is already in progress.
2470    ///
2471    /// The cancellation handler is submitted to the source's target queue once the
2472    /// the source's event handler has finished, indicating it is now safe to close
2473    /// the source's handle (i.e. file descriptor or mach port).
2474    ///
2475    /// See dispatch_source_set_cancel_handler() for more information.
2476    ///
2477    ///
2478    /// Parameter `source`: The dispatch source to be canceled.
2479    /// The result of passing NULL in this parameter is undefined.
2480    #[doc(alias = "dispatch_source_cancel")]
2481    #[inline]
2482    pub fn cancel(self: &DispatchSource) {
2483        extern "C" {
2484            fn dispatch_source_cancel(source: &DispatchSource);
2485        }
2486        unsafe { dispatch_source_cancel(self) }
2487    }
2488
2489    /// Tests whether the given dispatch source has been canceled.
2490    ///
2491    ///
2492    /// Parameter `source`: The dispatch source to be tested.
2493    /// The result of passing NULL in this parameter is undefined.
2494    ///
2495    ///
2496    /// Returns: Non-zero if canceled and zero if not canceled.
2497    #[doc(alias = "dispatch_source_testcancel")]
2498    #[must_use]
2499    #[inline]
2500    pub fn testcancel(self: &DispatchSource) -> isize {
2501        extern "C" {
2502            fn dispatch_source_testcancel(source: &DispatchSource) -> isize;
2503        }
2504        unsafe { dispatch_source_testcancel(self) }
2505    }
2506
2507    /// Returns the underlying system handle associated with this dispatch source.
2508    ///
2509    ///
2510    /// Parameter `source`: The result of passing NULL in this parameter is undefined.
2511    ///
2512    ///
2513    /// Returns: The return value should be interpreted according to the type of the dispatch
2514    /// source, and may be one of the following handles:
2515    ///
2516    /// DISPATCH_SOURCE_TYPE_DATA_ADD:        n/a
2517    /// DISPATCH_SOURCE_TYPE_DATA_OR:         n/a
2518    /// DISPATCH_SOURCE_TYPE_DATA_REPLACE:    n/a
2519    /// DISPATCH_SOURCE_TYPE_MACH_SEND:       mach port (mach_port_t)
2520    /// DISPATCH_SOURCE_TYPE_MACH_RECV:       mach port (mach_port_t)
2521    /// DISPATCH_SOURCE_TYPE_MEMORYPRESSURE   n/a
2522    /// DISPATCH_SOURCE_TYPE_PROC:            process identifier (pid_t)
2523    /// DISPATCH_SOURCE_TYPE_READ:            file descriptor (int)
2524    /// DISPATCH_SOURCE_TYPE_SIGNAL:          signal number (int)
2525    /// DISPATCH_SOURCE_TYPE_TIMER:           n/a
2526    /// DISPATCH_SOURCE_TYPE_VNODE:           file descriptor (int)
2527    /// DISPATCH_SOURCE_TYPE_WRITE:           file descriptor (int)
2528    #[doc(alias = "dispatch_source_get_handle")]
2529    #[must_use]
2530    #[inline]
2531    pub fn handle(self: &DispatchSource) -> usize {
2532        extern "C" {
2533            fn dispatch_source_get_handle(source: &DispatchSource) -> usize;
2534        }
2535        unsafe { dispatch_source_get_handle(self) }
2536    }
2537
2538    /// Returns the mask of events monitored by the dispatch source.
2539    ///
2540    ///
2541    /// Parameter `source`: The result of passing NULL in this parameter is undefined.
2542    ///
2543    ///
2544    /// Returns: The return value should be interpreted according to the type of the dispatch
2545    /// source, and may be one of the following flag sets:
2546    ///
2547    /// DISPATCH_SOURCE_TYPE_DATA_ADD:        n/a
2548    /// DISPATCH_SOURCE_TYPE_DATA_OR:         n/a
2549    /// DISPATCH_SOURCE_TYPE_DATA_REPLACE:    n/a
2550    /// DISPATCH_SOURCE_TYPE_MACH_SEND:       dispatch_source_mach_send_flags_t
2551    /// DISPATCH_SOURCE_TYPE_MACH_RECV:       dispatch_source_mach_recv_flags_t
2552    /// DISPATCH_SOURCE_TYPE_MEMORYPRESSURE   dispatch_source_memorypressure_flags_t
2553    /// DISPATCH_SOURCE_TYPE_PROC:            dispatch_source_proc_flags_t
2554    /// DISPATCH_SOURCE_TYPE_READ:            n/a
2555    /// DISPATCH_SOURCE_TYPE_SIGNAL:          n/a
2556    /// DISPATCH_SOURCE_TYPE_TIMER:           dispatch_source_timer_flags_t
2557    /// DISPATCH_SOURCE_TYPE_VNODE:           dispatch_source_vnode_flags_t
2558    /// DISPATCH_SOURCE_TYPE_WRITE:           n/a
2559    #[doc(alias = "dispatch_source_get_mask")]
2560    #[must_use]
2561    #[inline]
2562    pub fn mask(self: &DispatchSource) -> usize {
2563        extern "C" {
2564            fn dispatch_source_get_mask(source: &DispatchSource) -> usize;
2565        }
2566        unsafe { dispatch_source_get_mask(self) }
2567    }
2568
2569    /// Returns pending data for the dispatch source.
2570    ///
2571    ///
2572    /// This function is intended to be called from within the event handler block.
2573    /// The result of calling this function outside of the event handler callback is
2574    /// undefined.
2575    ///
2576    ///
2577    /// Parameter `source`: The result of passing NULL in this parameter is undefined.
2578    ///
2579    ///
2580    /// Returns: The return value should be interpreted according to the type of the dispatch
2581    /// source, and may be one of the following:
2582    ///
2583    /// DISPATCH_SOURCE_TYPE_DATA_ADD:        application defined data
2584    /// DISPATCH_SOURCE_TYPE_DATA_OR:         application defined data
2585    /// DISPATCH_SOURCE_TYPE_DATA_REPLACE:    application defined data
2586    /// DISPATCH_SOURCE_TYPE_MACH_SEND:       dispatch_source_mach_send_flags_t
2587    /// DISPATCH_SOURCE_TYPE_MACH_RECV:       dispatch_source_mach_recv_flags_t
2588    /// DISPATCH_SOURCE_TYPE_MEMORYPRESSURE   dispatch_source_memorypressure_flags_t
2589    /// DISPATCH_SOURCE_TYPE_PROC:            dispatch_source_proc_flags_t
2590    /// DISPATCH_SOURCE_TYPE_READ:            estimated bytes available to read
2591    /// DISPATCH_SOURCE_TYPE_SIGNAL:          number of signals delivered since
2592    /// the last handler invocation
2593    /// DISPATCH_SOURCE_TYPE_TIMER:           number of times the timer has fired
2594    /// since the last handler invocation
2595    /// DISPATCH_SOURCE_TYPE_VNODE:           dispatch_source_vnode_flags_t
2596    /// DISPATCH_SOURCE_TYPE_WRITE:           estimated buffer space available
2597    #[doc(alias = "dispatch_source_get_data")]
2598    #[must_use]
2599    #[inline]
2600    pub fn data(self: &DispatchSource) -> usize {
2601        extern "C" {
2602            fn dispatch_source_get_data(source: &DispatchSource) -> usize;
2603        }
2604        unsafe { dispatch_source_get_data(self) }
2605    }
2606
2607    /// Merges data into a dispatch source of type DISPATCH_SOURCE_TYPE_DATA_ADD,
2608    /// DISPATCH_SOURCE_TYPE_DATA_OR or DISPATCH_SOURCE_TYPE_DATA_REPLACE,
2609    /// and submits its event handler block to its target queue.
2610    ///
2611    ///
2612    /// Parameter `source`: The result of passing NULL in this parameter is undefined.
2613    ///
2614    ///
2615    /// Parameter `value`: The value to coalesce with the pending data using a logical OR or an ADD
2616    /// as specified by the dispatch source type. A value of zero has no effect
2617    /// and will not result in the submission of the event handler block.
2618    #[doc(alias = "dispatch_source_merge_data")]
2619    #[inline]
2620    pub fn merge_data(self: &DispatchSource, value: usize) {
2621        extern "C" {
2622            fn dispatch_source_merge_data(source: &DispatchSource, value: usize);
2623        }
2624        unsafe { dispatch_source_merge_data(self, value) }
2625    }
2626
2627    /// Sets a start time, interval, and leeway value for a timer source.
2628    ///
2629    ///
2630    /// Once this function returns, any pending source data accumulated for the
2631    /// previous timer values has been cleared; the next fire of the timer will
2632    /// occur at 'start', and every 'interval' nanoseconds thereafter until the
2633    /// timer source is canceled.
2634    ///
2635    /// Any fire of the timer may be delayed by the system in order to improve power
2636    /// consumption and system performance. The upper limit to the allowable delay
2637    /// may be configured with the 'leeway' argument, the lower limit is under the
2638    /// control of the system.
2639    ///
2640    /// For the initial timer fire at 'start', the upper limit to the allowable
2641    /// delay is set to 'leeway' nanoseconds. For the subsequent timer fires at
2642    /// 'start' + N * 'interval', the upper limit is MIN('leeway','interval'/2).
2643    ///
2644    /// The lower limit to the allowable delay may vary with process state such as
2645    /// visibility of application UI. If the specified timer source was created with
2646    /// a mask of DISPATCH_TIMER_STRICT, the system will make a best effort to
2647    /// strictly observe the provided 'leeway' value even if it is smaller than the
2648    /// current lower limit. Note that a minimal amount of delay is to be expected
2649    /// even if this flag is specified.
2650    ///
2651    /// The 'start' argument also determines which clock will be used for the timer:
2652    /// If 'start' is DISPATCH_TIME_NOW or was created with dispatch_time(3), the
2653    /// timer is based on up time (which is obtained from mach_absolute_time() on
2654    /// Apple platforms). If 'start' was created with dispatch_walltime(3), the
2655    /// timer is based on gettimeofday(3).
2656    ///
2657    /// Calling this function has no effect if the timer source has already been
2658    /// canceled.
2659    ///
2660    ///
2661    /// Parameter `start`: The start time of the timer. See dispatch_time() and dispatch_walltime()
2662    /// for more information.
2663    ///
2664    ///
2665    /// Parameter `interval`: The nanosecond interval for the timer. Use DISPATCH_TIME_FOREVER for a
2666    /// one-shot timer.
2667    ///
2668    ///
2669    /// Parameter `leeway`: The nanosecond leeway for the timer.
2670    #[doc(alias = "dispatch_source_set_timer")]
2671    #[inline]
2672    pub fn set_timer(self: &DispatchSource, start: DispatchTime, interval: u64, leeway: u64) {
2673        extern "C" {
2674            fn dispatch_source_set_timer(
2675                source: &DispatchSource,
2676                start: DispatchTime,
2677                interval: u64,
2678                leeway: u64,
2679            );
2680        }
2681        unsafe { dispatch_source_set_timer(self, start, interval, leeway) }
2682    }
2683
2684    #[doc(alias = "dispatch_source_set_registration_handler")]
2685    #[cfg(feature = "block2")]
2686    #[inline]
2687    pub unsafe fn set_registration_handler_with_block(
2688        self: &DispatchSource,
2689        handler: dispatch_block_t,
2690    ) {
2691        extern "C" {
2692            fn dispatch_source_set_registration_handler(
2693                source: &DispatchSource,
2694                handler: dispatch_block_t,
2695            );
2696        }
2697        unsafe { dispatch_source_set_registration_handler(self, handler) }
2698    }
2699
2700    /// Sets the registration handler function for the given dispatch source.
2701    ///
2702    ///
2703    /// See dispatch_source_set_registration_handler() for more details.
2704    ///
2705    ///
2706    /// Parameter `source`: The dispatch source to modify.
2707    /// The result of passing NULL in this parameter is undefined.
2708    ///
2709    ///
2710    /// Parameter `handler`: The registration handler function to submit to the source's target queue.
2711    /// The context parameter passed to the registration handler function is the
2712    /// current context of the dispatch source at the time the handler call is made.
2713    #[doc(alias = "dispatch_source_set_registration_handler_f")]
2714    #[inline]
2715    pub fn set_registration_handler_f(self: &DispatchSource, handler: dispatch_function_t) {
2716        extern "C" {
2717            fn dispatch_source_set_registration_handler_f(
2718                source: &DispatchSource,
2719                handler: dispatch_function_t,
2720            );
2721        }
2722        unsafe { dispatch_source_set_registration_handler_f(self, handler) }
2723    }
2724}
2725
2726impl DispatchGroup {
2727    /// Creates new group with which blocks may be associated.
2728    ///
2729    ///
2730    /// This function creates a new group with which blocks may be associated.
2731    /// The dispatch group may be used to wait for the completion of the blocks it
2732    /// references. The group object memory is freed with dispatch_release().
2733    ///
2734    ///
2735    /// Returns: The newly created group, or NULL on failure.
2736    #[doc(alias = "dispatch_group_create")]
2737    #[must_use]
2738    #[inline]
2739    pub fn new() -> DispatchRetained<DispatchGroup> {
2740        extern "C" {
2741            fn dispatch_group_create() -> Option<NonNull<DispatchGroup>>;
2742        }
2743        let ret = unsafe { dispatch_group_create() };
2744        let ret =
2745            ret.expect("function was marked as returning non-null, but actually returned NULL");
2746        unsafe { DispatchRetained::from_raw(ret) }
2747    }
2748
2749    #[doc(alias = "dispatch_group_async")]
2750    #[cfg(feature = "block2")]
2751    #[inline]
2752    pub unsafe fn exec_async_with_block(
2753        self: &DispatchGroup,
2754        queue: &DispatchQueue,
2755        block: dispatch_block_t,
2756    ) {
2757        extern "C" {
2758            fn dispatch_group_async(
2759                group: &DispatchGroup,
2760                queue: &DispatchQueue,
2761                block: dispatch_block_t,
2762            );
2763        }
2764        unsafe { dispatch_group_async(self, queue, block) }
2765    }
2766
2767    /// Submits a function to a dispatch queue and associates the block with the
2768    /// given dispatch group.
2769    ///
2770    ///
2771    /// See dispatch_group_async() for details.
2772    ///
2773    ///
2774    /// Parameter `group`: A dispatch group to associate with the submitted function.
2775    /// The result of passing NULL in this parameter is undefined.
2776    ///
2777    ///
2778    /// Parameter `queue`: The dispatch queue to which the function will be submitted for asynchronous
2779    /// invocation.
2780    ///
2781    ///
2782    /// Parameter `context`: The application-defined context parameter to pass to the function.
2783    ///
2784    ///
2785    /// Parameter `work`: The application-defined function to invoke on the target queue. The first
2786    /// parameter passed to this function is the context provided to
2787    /// dispatch_group_async_f().
2788    #[doc(alias = "dispatch_group_async_f")]
2789    #[inline]
2790    pub unsafe fn exec_async_f(
2791        self: &DispatchGroup,
2792        queue: &DispatchQueue,
2793        context: *mut c_void,
2794        work: dispatch_function_t,
2795    ) {
2796        extern "C" {
2797            fn dispatch_group_async_f(
2798                group: &DispatchGroup,
2799                queue: &DispatchQueue,
2800                context: *mut c_void,
2801                work: dispatch_function_t,
2802            );
2803        }
2804        unsafe { dispatch_group_async_f(self, queue, context, work) }
2805    }
2806}
2807
2808/// Wait synchronously until all the blocks associated with a group have
2809/// completed or until the specified timeout has elapsed.
2810///
2811///
2812/// This function waits for the completion of the blocks associated with the
2813/// given dispatch group, and returns after all blocks have completed or when
2814/// the specified timeout has elapsed.
2815///
2816/// This function will return immediately if there are no blocks associated
2817/// with the dispatch group (i.e. the group is empty).
2818///
2819/// The result of calling this function from multiple threads simultaneously
2820/// with the same dispatch group is undefined.
2821///
2822/// After the successful return of this function, the dispatch group is empty.
2823/// It may either be released with dispatch_release() or re-used for additional
2824/// blocks. See dispatch_group_async() for more information.
2825///
2826///
2827/// Parameter `group`: The dispatch group to wait on.
2828/// The result of passing NULL in this parameter is undefined.
2829///
2830///
2831/// Parameter `timeout`: When to timeout (see dispatch_time). As a convenience, there are the
2832/// DISPATCH_TIME_NOW and DISPATCH_TIME_FOREVER constants.
2833///
2834///
2835/// Returns: Returns zero on success (all blocks associated with the group completed
2836/// within the specified timeout) or non-zero on error (i.e. timed out).
2837#[inline]
2838pub extern "C" fn dispatch_group_wait(group: &DispatchGroup, timeout: DispatchTime) -> isize {
2839    extern "C" {
2840        fn dispatch_group_wait(group: &DispatchGroup, timeout: DispatchTime) -> isize;
2841    }
2842    unsafe { dispatch_group_wait(group, timeout) }
2843}
2844
2845impl DispatchGroup {
2846    #[doc(alias = "dispatch_group_notify")]
2847    #[cfg(feature = "block2")]
2848    #[inline]
2849    pub unsafe fn notify_with_block(
2850        self: &DispatchGroup,
2851        queue: &DispatchQueue,
2852        block: dispatch_block_t,
2853    ) {
2854        extern "C" {
2855            fn dispatch_group_notify(
2856                group: &DispatchGroup,
2857                queue: &DispatchQueue,
2858                block: dispatch_block_t,
2859            );
2860        }
2861        unsafe { dispatch_group_notify(self, queue, block) }
2862    }
2863
2864    /// Schedule a function to be submitted to a queue when all the blocks
2865    /// associated with a group have completed.
2866    ///
2867    ///
2868    /// See dispatch_group_notify() for details.
2869    ///
2870    ///
2871    /// Parameter `group`: The dispatch group to observe.
2872    /// The result of passing NULL in this parameter is undefined.
2873    ///
2874    ///
2875    /// Parameter `context`: The application-defined context parameter to pass to the function.
2876    ///
2877    ///
2878    /// Parameter `work`: The application-defined function to invoke on the target queue. The first
2879    /// parameter passed to this function is the context provided to
2880    /// dispatch_group_notify_f().
2881    #[doc(alias = "dispatch_group_notify_f")]
2882    #[inline]
2883    pub unsafe fn notify_f(
2884        self: &DispatchGroup,
2885        queue: &DispatchQueue,
2886        context: *mut c_void,
2887        work: dispatch_function_t,
2888    ) {
2889        extern "C" {
2890            fn dispatch_group_notify_f(
2891                group: &DispatchGroup,
2892                queue: &DispatchQueue,
2893                context: *mut c_void,
2894                work: dispatch_function_t,
2895            );
2896        }
2897        unsafe { dispatch_group_notify_f(self, queue, context, work) }
2898    }
2899}
2900
2901extern "C" {
2902    /// Manually indicate a block has entered the group
2903    ///
2904    ///
2905    /// Calling this function indicates another block has joined the group through
2906    /// a means other than dispatch_group_async(). Calls to this function must be
2907    /// balanced with dispatch_group_leave().
2908    ///
2909    ///
2910    /// Parameter `group`: The dispatch group to update.
2911    /// The result of passing NULL in this parameter is undefined.
2912    pub fn dispatch_group_enter(group: &DispatchGroup);
2913}
2914
2915impl DispatchGroup {
2916    /// Manually indicate a block in the group has completed
2917    ///
2918    ///
2919    /// Calling this function indicates block has completed and left the dispatch
2920    /// group by a means other than dispatch_group_async().
2921    ///
2922    ///
2923    /// Parameter `group`: The dispatch group to update.
2924    /// The result of passing NULL in this parameter is undefined.
2925    #[doc(alias = "dispatch_group_leave")]
2926    #[inline]
2927    pub unsafe fn leave(self: &DispatchGroup) {
2928        extern "C" {
2929            fn dispatch_group_leave(group: &DispatchGroup);
2930        }
2931        unsafe { dispatch_group_leave(self) }
2932    }
2933}
2934
2935impl DispatchSemaphore {
2936    /// Creates new counting semaphore with an initial value.
2937    ///
2938    ///
2939    /// Passing zero for the value is useful for when two threads need to reconcile
2940    /// the completion of a particular event. Passing a value greater than zero is
2941    /// useful for managing a finite pool of resources, where the pool size is equal
2942    /// to the value.
2943    ///
2944    ///
2945    /// Parameter `value`: The starting value for the semaphore. Passing a value less than zero will
2946    /// cause NULL to be returned.
2947    ///
2948    ///
2949    /// Returns: The newly created semaphore, or NULL on failure.
2950    #[doc(alias = "dispatch_semaphore_create")]
2951    #[must_use]
2952    #[inline]
2953    pub fn new(value: isize) -> DispatchRetained<DispatchSemaphore> {
2954        extern "C" {
2955            fn dispatch_semaphore_create(value: isize) -> Option<NonNull<DispatchSemaphore>>;
2956        }
2957        let ret = unsafe { dispatch_semaphore_create(value) };
2958        let ret =
2959            ret.expect("function was marked as returning non-null, but actually returned NULL");
2960        unsafe { DispatchRetained::from_raw(ret) }
2961    }
2962
2963    /// Wait (decrement) for a semaphore.
2964    ///
2965    ///
2966    /// Decrement the counting semaphore. If the resulting value is less than zero,
2967    /// this function waits for a signal to occur before returning. If the timeout is
2968    /// reached without a signal being received, the semaphore is re-incremented
2969    /// before the function returns.
2970    ///
2971    ///
2972    /// Parameter `dsema`: The semaphore. The result of passing NULL in this parameter is undefined.
2973    ///
2974    ///
2975    /// Parameter `timeout`: When to timeout (see dispatch_time). As a convenience, there are the
2976    /// DISPATCH_TIME_NOW and DISPATCH_TIME_FOREVER constants.
2977    ///
2978    ///
2979    /// Returns: Returns zero on success, or non-zero if the timeout occurred.
2980    #[doc(alias = "dispatch_semaphore_wait")]
2981    #[inline]
2982    pub fn wait(self: &DispatchSemaphore, timeout: DispatchTime) -> isize {
2983        extern "C" {
2984            fn dispatch_semaphore_wait(dsema: &DispatchSemaphore, timeout: DispatchTime) -> isize;
2985        }
2986        unsafe { dispatch_semaphore_wait(self, timeout) }
2987    }
2988
2989    /// Signal (increment) a semaphore.
2990    ///
2991    ///
2992    /// Increment the counting semaphore. If the previous value was less than zero,
2993    /// this function wakes a waiting thread before returning.
2994    ///
2995    ///
2996    /// Parameter `dsema`: The counting semaphore.
2997    /// The result of passing NULL in this parameter is undefined.
2998    ///
2999    ///
3000    /// Returns: This function returns non-zero if a thread is woken. Otherwise, zero is
3001    /// returned.
3002    #[doc(alias = "dispatch_semaphore_signal")]
3003    #[inline]
3004    pub fn signal(self: &DispatchSemaphore) -> isize {
3005        extern "C" {
3006            fn dispatch_semaphore_signal(dsema: &DispatchSemaphore) -> isize;
3007        }
3008        unsafe { dispatch_semaphore_signal(self) }
3009    }
3010}
3011
3012/// A predicate for use with dispatch_once(). It must be initialized to zero.
3013/// Note: static and global variables default to zero.
3014///
3015/// See also [Apple's documentation](https://developer.apple.com/documentation/dispatch/dispatch_once_t?language=objc)
3016pub type dispatch_once_t = isize;
3017
3018impl DispatchOnce {
3019    #[doc(alias = "dispatch_once")]
3020    #[cfg(feature = "block2")]
3021    #[inline]
3022    pub unsafe fn once_with_block(predicate: NonNull<dispatch_once_t>, block: dispatch_block_t) {
3023        extern "C" {
3024            fn dispatch_once(predicate: NonNull<dispatch_once_t>, block: dispatch_block_t);
3025        }
3026        unsafe { dispatch_once(predicate, block) }
3027    }
3028
3029    #[doc(alias = "dispatch_once_f")]
3030    #[inline]
3031    pub unsafe fn once_f(
3032        predicate: NonNull<dispatch_once_t>,
3033        context: *mut c_void,
3034        function: dispatch_function_t,
3035    ) {
3036        extern "C" {
3037            fn dispatch_once_f(
3038                predicate: NonNull<dispatch_once_t>,
3039                context: *mut c_void,
3040                function: dispatch_function_t,
3041            );
3042        }
3043        unsafe { dispatch_once_f(predicate, context, function) }
3044    }
3045}
3046
3047extern "C" {
3048    /// [Apple's documentation](https://developer.apple.com/documentation/dispatch/_dispatch_data_empty?language=objc)
3049    pub static _dispatch_data_empty: DispatchData;
3050}
3051
3052extern "C" {
3053    /// [Apple's documentation](https://developer.apple.com/documentation/dispatch/_dispatch_data_destructor_free?language=objc)
3054    #[cfg(feature = "block2")]
3055    pub static _dispatch_data_destructor_free: dispatch_block_t;
3056}
3057
3058extern "C" {
3059    /// [Apple's documentation](https://developer.apple.com/documentation/dispatch/_dispatch_data_destructor_munmap?language=objc)
3060    #[cfg(feature = "block2")]
3061    pub static _dispatch_data_destructor_munmap: dispatch_block_t;
3062}
3063
3064impl DispatchData {
3065    /// Creates a dispatch data object from the given contiguous buffer of memory. If
3066    /// a non-default destructor is provided, ownership of the buffer remains with
3067    /// the caller (i.e. the bytes will not be copied). The last release of the data
3068    /// object will result in the invocation of the specified destructor on the
3069    /// specified queue to free the buffer.
3070    ///
3071    /// If the DISPATCH_DATA_DESTRUCTOR_FREE destructor is provided the buffer will
3072    /// be freed via free(3) and the queue argument ignored.
3073    ///
3074    /// If the DISPATCH_DATA_DESTRUCTOR_DEFAULT destructor is provided, data object
3075    /// creation will copy the buffer into internal memory managed by the system.
3076    ///
3077    ///
3078    /// Parameter `buffer`: A contiguous buffer of data.
3079    ///
3080    /// Parameter `size`: The size of the contiguous buffer of data.
3081    ///
3082    /// Parameter `queue`: The queue to which the destructor should be submitted.
3083    ///
3084    /// Parameter `destructor`: The destructor responsible for freeing the data when it
3085    /// is no longer needed.
3086    ///
3087    /// Returns: A newly created dispatch data object.
3088    #[doc(alias = "dispatch_data_create")]
3089    #[cfg(feature = "block2")]
3090    #[must_use]
3091    #[inline]
3092    pub unsafe fn new(
3093        buffer: NonNull<c_void>,
3094        size: usize,
3095        queue: Option<&DispatchQueue>,
3096        destructor: dispatch_block_t,
3097    ) -> DispatchRetained<DispatchData> {
3098        extern "C" {
3099            fn dispatch_data_create(
3100                buffer: NonNull<c_void>,
3101                size: usize,
3102                queue: Option<&DispatchQueue>,
3103                destructor: dispatch_block_t,
3104            ) -> Option<NonNull<DispatchData>>;
3105        }
3106        let ret = unsafe { dispatch_data_create(buffer, size, queue, destructor) };
3107        let ret =
3108            ret.expect("function was marked as returning non-null, but actually returned NULL");
3109        unsafe { DispatchRetained::from_raw(ret) }
3110    }
3111
3112    /// Returns the logical size of the memory region(s) represented by the specified
3113    /// dispatch data object.
3114    ///
3115    ///
3116    /// Parameter `data`: The dispatch data object to query.
3117    ///
3118    /// Returns: The number of bytes represented by the data object.
3119    #[doc(alias = "dispatch_data_get_size")]
3120    #[inline]
3121    pub fn size(self: &DispatchData) -> usize {
3122        extern "C" {
3123            fn dispatch_data_get_size(data: &DispatchData) -> usize;
3124        }
3125        unsafe { dispatch_data_get_size(self) }
3126    }
3127
3128    /// Maps the memory represented by the specified dispatch data object as a single
3129    /// contiguous memory region and returns a new data object representing it.
3130    /// If non-NULL references to a pointer and a size variable are provided, they
3131    /// are filled with the location and extent of that region. These allow direct
3132    /// read access to the represented memory, but are only valid until the returned
3133    /// object is released. Under ARC, if that object is held in a variable with
3134    /// automatic storage, care needs to be taken to ensure that it is not released
3135    /// by the compiler before memory access via the pointer has been completed.
3136    ///
3137    ///
3138    /// Parameter `data`: The dispatch data object to map.
3139    ///
3140    /// Parameter `buffer_ptr`: A pointer to a pointer variable to be filled with the
3141    /// location of the mapped contiguous memory region, or
3142    /// NULL.
3143    ///
3144    /// Parameter `size_ptr`: A pointer to a size_t variable to be filled with the
3145    /// size of the mapped contiguous memory region, or NULL.
3146    ///
3147    /// Returns: A newly created dispatch data object.
3148    #[doc(alias = "dispatch_data_create_map")]
3149    #[must_use]
3150    #[inline]
3151    pub unsafe fn map(
3152        self: &DispatchData,
3153        buffer_ptr: *mut *const c_void,
3154        size_ptr: *mut usize,
3155    ) -> DispatchRetained<DispatchData> {
3156        extern "C" {
3157            fn dispatch_data_create_map(
3158                data: &DispatchData,
3159                buffer_ptr: *mut *const c_void,
3160                size_ptr: *mut usize,
3161            ) -> Option<NonNull<DispatchData>>;
3162        }
3163        let ret = unsafe { dispatch_data_create_map(self, buffer_ptr, size_ptr) };
3164        let ret =
3165            ret.expect("function was marked as returning non-null, but actually returned NULL");
3166        unsafe { DispatchRetained::from_raw(ret) }
3167    }
3168
3169    /// Returns a new dispatch data object representing the concatenation of the
3170    /// specified data objects. Those objects may be released by the application
3171    /// after the call returns (however, the system might not deallocate the memory
3172    /// region(s) described by them until the newly created object has also been
3173    /// released).
3174    ///
3175    ///
3176    /// Parameter `data1`: The data object representing the region(s) of memory to place
3177    /// at the beginning of the newly created object.
3178    ///
3179    /// Parameter `data2`: The data object representing the region(s) of memory to place
3180    /// at the end of the newly created object.
3181    ///
3182    /// Returns: A newly created object representing the concatenation of the
3183    /// data1 and data2 objects.
3184    #[doc(alias = "dispatch_data_create_concat")]
3185    #[must_use]
3186    #[inline]
3187    pub fn concat(self: &DispatchData, data2: &DispatchData) -> DispatchRetained<DispatchData> {
3188        extern "C" {
3189            fn dispatch_data_create_concat(
3190                data1: &DispatchData,
3191                data2: &DispatchData,
3192            ) -> Option<NonNull<DispatchData>>;
3193        }
3194        let ret = unsafe { dispatch_data_create_concat(self, data2) };
3195        let ret =
3196            ret.expect("function was marked as returning non-null, but actually returned NULL");
3197        unsafe { DispatchRetained::from_raw(ret) }
3198    }
3199
3200    /// Returns a new dispatch data object representing a subrange of the specified
3201    /// data object, which may be released by the application after the call returns
3202    /// (however, the system might not deallocate the memory region(s) described by
3203    /// that object until the newly created object has also been released).
3204    ///
3205    ///
3206    /// Parameter `data`: The data object representing the region(s) of memory to
3207    /// create a subrange of.
3208    ///
3209    /// Parameter `offset`: The offset into the data object where the subrange
3210    /// starts.
3211    ///
3212    /// Parameter `length`: The length of the range.
3213    ///
3214    /// Returns: A newly created object representing the specified
3215    /// subrange of the data object.
3216    #[doc(alias = "dispatch_data_create_subrange")]
3217    #[must_use]
3218    #[inline]
3219    pub unsafe fn subrange(
3220        self: &DispatchData,
3221        offset: usize,
3222        length: usize,
3223    ) -> DispatchRetained<DispatchData> {
3224        extern "C" {
3225            fn dispatch_data_create_subrange(
3226                data: &DispatchData,
3227                offset: usize,
3228                length: usize,
3229            ) -> Option<NonNull<DispatchData>>;
3230        }
3231        let ret = unsafe { dispatch_data_create_subrange(self, offset, length) };
3232        let ret =
3233            ret.expect("function was marked as returning non-null, but actually returned NULL");
3234        unsafe { DispatchRetained::from_raw(ret) }
3235    }
3236}
3237
3238/// A block to be invoked for every contiguous memory region in a data object.
3239///
3240///
3241/// Parameter `region`: A data object representing the current region.
3242///
3243/// Parameter `offset`: The logical offset of the current region to the start
3244/// of the data object.
3245///
3246/// Parameter `buffer`: The location of the memory for the current region.
3247///
3248/// Parameter `size`: The size of the memory for the current region.
3249///
3250/// Returns: A Boolean indicating whether traversal should continue.
3251///
3252/// See also [Apple's documentation](https://developer.apple.com/documentation/dispatch/dispatch_data_applier_t?language=objc)
3253#[cfg(feature = "block2")]
3254pub type dispatch_data_applier_t =
3255    *mut block2::DynBlock<dyn Fn(NonNull<DispatchData>, usize, NonNull<c_void>, usize) -> bool>;
3256
3257impl DispatchData {
3258    /// Traverse the memory regions represented by the specified dispatch data object
3259    /// in logical order and invoke the specified block once for every contiguous
3260    /// memory region encountered.
3261    ///
3262    /// Each invocation of the block is passed a data object representing the current
3263    /// region and its logical offset, along with the memory location and extent of
3264    /// the region. These allow direct read access to the memory region, but are only
3265    /// valid until the passed-in region object is released. Note that the region
3266    /// object is released by the system when the block returns, it is the
3267    /// responsibility of the application to retain it if the region object or the
3268    /// associated memory location are needed after the block returns.
3269    ///
3270    ///
3271    /// Parameter `data`: The data object to traverse.
3272    ///
3273    /// Parameter `applier`: The block to be invoked for every contiguous memory
3274    /// region in the data object.
3275    ///
3276    /// Returns: A Boolean indicating whether traversal completed
3277    /// successfully.
3278    #[doc(alias = "dispatch_data_apply")]
3279    #[cfg(feature = "block2")]
3280    #[inline]
3281    pub unsafe fn apply(self: &DispatchData, applier: dispatch_data_applier_t) -> bool {
3282        extern "C" {
3283            fn dispatch_data_apply(data: &DispatchData, applier: dispatch_data_applier_t) -> bool;
3284        }
3285        unsafe { dispatch_data_apply(self, applier) }
3286    }
3287
3288    /// Finds the contiguous memory region containing the specified location among
3289    /// the regions represented by the specified object and returns a copy of the
3290    /// internal dispatch data object representing that region along with its logical
3291    /// offset in the specified object.
3292    ///
3293    ///
3294    /// Parameter `data`: The dispatch data object to query.
3295    ///
3296    /// Parameter `location`: The logical position in the data object to query.
3297    ///
3298    /// Parameter `offset_ptr`: A pointer to a size_t variable to be filled with the
3299    /// logical offset of the returned region object to the
3300    /// start of the queried data object.
3301    ///
3302    /// Returns: A newly created dispatch data object.
3303    #[doc(alias = "dispatch_data_copy_region")]
3304    #[must_use]
3305    #[inline]
3306    pub unsafe fn region(
3307        self: &DispatchData,
3308        location: usize,
3309        offset_ptr: NonNull<usize>,
3310    ) -> DispatchRetained<DispatchData> {
3311        extern "C" {
3312            fn dispatch_data_copy_region(
3313                data: &DispatchData,
3314                location: usize,
3315                offset_ptr: NonNull<usize>,
3316            ) -> Option<NonNull<DispatchData>>;
3317        }
3318        let ret = unsafe { dispatch_data_copy_region(self, location, offset_ptr) };
3319        let ret =
3320            ret.expect("function was marked as returning non-null, but actually returned NULL");
3321        unsafe { DispatchRetained::from_raw(ret) }
3322    }
3323}
3324
3325/// [Apple's documentation](https://developer.apple.com/documentation/dispatch/dispatch_fd_t?language=objc)
3326pub type dispatch_fd_t = c_int;
3327
3328extern "C" {
3329    /// Schedule a read operation for asynchronous execution on the specified file
3330    /// descriptor. The specified handler is enqueued with the data read from the
3331    /// file descriptor when the operation has completed or an error occurs.
3332    ///
3333    /// The data object passed to the handler will be automatically released by the
3334    /// system when the handler returns. It is the responsibility of the application
3335    /// to retain, concatenate or copy the data object if it is needed after the
3336    /// handler returns.
3337    ///
3338    /// The data object passed to the handler will only contain as much data as is
3339    /// currently available from the file descriptor (up to the specified length).
3340    ///
3341    /// If an unrecoverable error occurs on the file descriptor, the handler will be
3342    /// enqueued with the appropriate error code along with a data object of any data
3343    /// that could be read successfully.
3344    ///
3345    /// An invocation of the handler with an error code of zero and an empty data
3346    /// object indicates that EOF was reached.
3347    ///
3348    /// The system takes control of the file descriptor until the handler is
3349    /// enqueued, and during this time file descriptor flags such as O_NONBLOCK will
3350    /// be modified by the system on behalf of the application. It is an error for
3351    /// the application to modify a file descriptor directly while it is under the
3352    /// control of the system, but it may create additional dispatch I/O convenience
3353    /// operations or dispatch I/O channels associated with that file descriptor.
3354    ///
3355    ///
3356    /// Parameter `fd`: The file descriptor from which to read the data.
3357    ///
3358    /// Parameter `length`: The length of data to read from the file descriptor,
3359    /// or SIZE_MAX to indicate that all of the data currently
3360    /// available from the file descriptor should be read.
3361    ///
3362    /// Parameter `queue`: The dispatch queue to which the handler should be
3363    /// submitted.
3364    ///
3365    /// Parameter `handler`: The handler to enqueue when data is ready to be
3366    /// delivered.
3367    /// param data    The data read from the file descriptor.
3368    /// param error    An errno condition for the read operation or
3369    /// zero if the read was successful.
3370    #[cfg(feature = "block2")]
3371    pub fn dispatch_read(
3372        fd: dispatch_fd_t,
3373        length: usize,
3374        queue: &DispatchQueue,
3375        handler: &block2::DynBlock<dyn Fn(NonNull<DispatchData>, c_int)>,
3376    );
3377}
3378
3379extern "C" {
3380    /// Schedule a write operation for asynchronous execution on the specified file
3381    /// descriptor. The specified handler is enqueued when the operation has
3382    /// completed or an error occurs.
3383    ///
3384    /// If an unrecoverable error occurs on the file descriptor, the handler will be
3385    /// enqueued with the appropriate error code along with the data that could not
3386    /// be successfully written.
3387    ///
3388    /// An invocation of the handler with an error code of zero indicates that the
3389    /// data was fully written to the channel.
3390    ///
3391    /// The system takes control of the file descriptor until the handler is
3392    /// enqueued, and during this time file descriptor flags such as O_NONBLOCK will
3393    /// be modified by the system on behalf of the application. It is an error for
3394    /// the application to modify a file descriptor directly while it is under the
3395    /// control of the system, but it may create additional dispatch I/O convenience
3396    /// operations or dispatch I/O channels associated with that file descriptor.
3397    ///
3398    ///
3399    /// Parameter `fd`: The file descriptor to which to write the data.
3400    ///
3401    /// Parameter `data`: The data object to write to the file descriptor.
3402    ///
3403    /// Parameter `queue`: The dispatch queue to which the handler should be
3404    /// submitted.
3405    ///
3406    /// Parameter `handler`: The handler to enqueue when the data has been written.
3407    /// param data    The data that could not be written to the I/O
3408    /// channel, or NULL.
3409    /// param error    An errno condition for the write operation or
3410    /// zero if the write was successful.
3411    #[cfg(feature = "block2")]
3412    pub fn dispatch_write(
3413        fd: dispatch_fd_t,
3414        data: &DispatchData,
3415        queue: &DispatchQueue,
3416        handler: &block2::DynBlock<dyn Fn(*mut DispatchData, c_int)>,
3417    );
3418}
3419
3420impl DispatchIO {
3421    /// Create a dispatch I/O channel associated with a file descriptor. The system
3422    /// takes control of the file descriptor until the channel is closed, an error
3423    /// occurs on the file descriptor or all references to the channel are released.
3424    /// At that time the specified cleanup handler will be enqueued and control over
3425    /// the file descriptor relinquished.
3426    ///
3427    /// While a file descriptor is under the control of a dispatch I/O channel, file
3428    /// descriptor flags such as O_NONBLOCK will be modified by the system on behalf
3429    /// of the application. It is an error for the application to modify a file
3430    /// descriptor directly while it is under the control of a dispatch I/O channel,
3431    /// but it may create additional channels associated with that file descriptor.
3432    ///
3433    ///
3434    /// Parameter `type`: The desired type of I/O channel (DISPATCH_IO_STREAM
3435    /// or DISPATCH_IO_RANDOM).
3436    ///
3437    /// Parameter `fd`: The file descriptor to associate with the I/O channel.
3438    ///
3439    /// Parameter `queue`: The dispatch queue to which the handler should be submitted.
3440    ///
3441    /// Parameter `cleanup_handler`: The handler to enqueue when the system
3442    /// relinquishes control over the file descriptor.
3443    /// param error        An errno condition if control is relinquished
3444    /// because channel creation failed, zero otherwise.
3445    ///
3446    /// Returns: The newly created dispatch I/O channel or NULL if an error
3447    /// occurred (invalid type specified).
3448    #[doc(alias = "dispatch_io_create")]
3449    #[cfg(feature = "block2")]
3450    #[must_use]
3451    #[inline]
3452    pub unsafe fn new(
3453        r#type: DispatchIOStreamType,
3454        fd: dispatch_fd_t,
3455        queue: &DispatchQueue,
3456        cleanup_handler: &block2::DynBlock<dyn Fn(c_int)>,
3457    ) -> DispatchRetained<DispatchIO> {
3458        extern "C" {
3459            fn dispatch_io_create(
3460                r#type: DispatchIOStreamType,
3461                fd: dispatch_fd_t,
3462                queue: &DispatchQueue,
3463                cleanup_handler: &block2::DynBlock<dyn Fn(c_int)>,
3464            ) -> Option<NonNull<DispatchIO>>;
3465        }
3466        let ret = unsafe { dispatch_io_create(r#type, fd, queue, cleanup_handler) };
3467        let ret =
3468            ret.expect("function was marked as returning non-null, but actually returned NULL");
3469        unsafe { DispatchRetained::from_raw(ret) }
3470    }
3471
3472    /// Create a dispatch I/O channel associated with a path name. The specified
3473    /// path, oflag and mode parameters will be passed to open(2) when the first I/O
3474    /// operation on the channel is ready to execute and the resulting file
3475    /// descriptor will remain open and under the control of the system until the
3476    /// channel is closed, an error occurs on the file descriptor or all references
3477    /// to the channel are released. At that time the file descriptor will be closed
3478    /// and the specified cleanup handler will be enqueued.
3479    ///
3480    ///
3481    /// Parameter `type`: The desired type of I/O channel (DISPATCH_IO_STREAM
3482    /// or DISPATCH_IO_RANDOM).
3483    ///
3484    /// Parameter `path`: The absolute path to associate with the I/O channel.
3485    ///
3486    /// Parameter `oflag`: The flags to pass to open(2) when opening the file at
3487    /// path.
3488    ///
3489    /// Parameter `mode`: The mode to pass to open(2) when creating the file at
3490    /// path (i.e. with flag O_CREAT), zero otherwise.
3491    ///
3492    /// Parameter `queue`: The dispatch queue to which the handler should be
3493    /// submitted.
3494    ///
3495    /// Parameter `cleanup_handler`: The handler to enqueue when the system
3496    /// has closed the file at path.
3497    /// param error        An errno condition if control is relinquished
3498    /// because channel creation or opening of the
3499    /// specified file failed, zero otherwise.
3500    ///
3501    /// Returns: The newly created dispatch I/O channel or NULL if an error
3502    /// occurred (invalid type or non-absolute path specified).
3503    #[doc(alias = "dispatch_io_create_with_path")]
3504    #[cfg(all(feature = "block2", feature = "libc"))]
3505    #[must_use]
3506    #[inline]
3507    pub unsafe fn with_path(
3508        r#type: DispatchIOStreamType,
3509        path: NonNull<c_char>,
3510        oflag: c_int,
3511        mode: libc::mode_t,
3512        queue: &DispatchQueue,
3513        cleanup_handler: &block2::DynBlock<dyn Fn(c_int)>,
3514    ) -> DispatchRetained<DispatchIO> {
3515        extern "C" {
3516            fn dispatch_io_create_with_path(
3517                r#type: DispatchIOStreamType,
3518                path: NonNull<c_char>,
3519                oflag: c_int,
3520                mode: libc::mode_t,
3521                queue: &DispatchQueue,
3522                cleanup_handler: &block2::DynBlock<dyn Fn(c_int)>,
3523            ) -> Option<NonNull<DispatchIO>>;
3524        }
3525        let ret = unsafe {
3526            dispatch_io_create_with_path(r#type, path, oflag, mode, queue, cleanup_handler)
3527        };
3528        let ret =
3529            ret.expect("function was marked as returning non-null, but actually returned NULL");
3530        unsafe { DispatchRetained::from_raw(ret) }
3531    }
3532
3533    /// Create a new dispatch I/O channel from an existing dispatch I/O channel.
3534    /// The new channel inherits the file descriptor or path name associated with
3535    /// the existing channel, but not its channel type or policies.
3536    ///
3537    /// If the existing channel is associated with a file descriptor, control by the
3538    /// system over that file descriptor is extended until the new channel is also
3539    /// closed, an error occurs on the file descriptor, or all references to both
3540    /// channels are released. At that time the specified cleanup handler will be
3541    /// enqueued and control over the file descriptor relinquished.
3542    ///
3543    /// While a file descriptor is under the control of a dispatch I/O channel, file
3544    /// descriptor flags such as O_NONBLOCK will be modified by the system on behalf
3545    /// of the application. It is an error for the application to modify a file
3546    /// descriptor directly while it is under the control of a dispatch I/O channel,
3547    /// but it may create additional channels associated with that file descriptor.
3548    ///
3549    ///
3550    /// Parameter `type`: The desired type of I/O channel (DISPATCH_IO_STREAM
3551    /// or DISPATCH_IO_RANDOM).
3552    ///
3553    /// Parameter `io`: The existing channel to create the new I/O channel from.
3554    ///
3555    /// Parameter `queue`: The dispatch queue to which the handler should be submitted.
3556    ///
3557    /// Parameter `cleanup_handler`: The handler to enqueue when the system
3558    /// relinquishes control over the file descriptor
3559    /// (resp. closes the file at path) associated with
3560    /// the existing channel.
3561    /// param error        An errno condition if control is relinquished
3562    /// because channel creation failed, zero otherwise.
3563    ///
3564    /// Returns: The newly created dispatch I/O channel or NULL if an error
3565    /// occurred (invalid type specified).
3566    #[doc(alias = "dispatch_io_create_with_io")]
3567    #[cfg(feature = "block2")]
3568    #[must_use]
3569    #[inline]
3570    pub fn with_io(
3571        r#type: DispatchIOStreamType,
3572        io: &DispatchIO,
3573        queue: &DispatchQueue,
3574        cleanup_handler: &block2::DynBlock<dyn Fn(c_int)>,
3575    ) -> DispatchRetained<DispatchIO> {
3576        extern "C" {
3577            fn dispatch_io_create_with_io(
3578                r#type: DispatchIOStreamType,
3579                io: &DispatchIO,
3580                queue: &DispatchQueue,
3581                cleanup_handler: &block2::DynBlock<dyn Fn(c_int)>,
3582            ) -> Option<NonNull<DispatchIO>>;
3583        }
3584        let ret = unsafe { dispatch_io_create_with_io(r#type, io, queue, cleanup_handler) };
3585        let ret =
3586            ret.expect("function was marked as returning non-null, but actually returned NULL");
3587        unsafe { DispatchRetained::from_raw(ret) }
3588    }
3589}
3590
3591/// The prototype of I/O handler blocks for dispatch I/O operations.
3592///
3593///
3594/// Parameter `done`: A flag indicating whether the operation is complete.
3595///
3596/// Parameter `data`: The data object to be handled.
3597///
3598/// Parameter `error`: An errno condition for the operation.
3599///
3600/// See also [Apple's documentation](https://developer.apple.com/documentation/dispatch/dispatch_io_handler_t?language=objc)
3601#[cfg(feature = "block2")]
3602pub type dispatch_io_handler_t = *mut block2::DynBlock<dyn Fn(bool, *mut DispatchData, c_int)>;
3603
3604impl DispatchIO {
3605    /// Schedule a read operation for asynchronous execution on the specified I/O
3606    /// channel. The I/O handler is enqueued one or more times depending on the
3607    /// general load of the system and the policy specified on the I/O channel.
3608    ///
3609    /// Any data read from the channel is described by the dispatch data object
3610    /// passed to the I/O handler. This object will be automatically released by the
3611    /// system when the I/O handler returns. It is the responsibility of the
3612    /// application to retain, concatenate or copy the data object if it is needed
3613    /// after the I/O handler returns.
3614    ///
3615    /// Dispatch I/O handlers are not reentrant. The system will ensure that no new
3616    /// I/O handler instance is invoked until the previously enqueued handler block
3617    /// has returned.
3618    ///
3619    /// An invocation of the I/O handler with the done flag set indicates that the
3620    /// read operation is complete and that the handler will not be enqueued again.
3621    ///
3622    /// If an unrecoverable error occurs on the I/O channel's underlying file
3623    /// descriptor, the I/O handler will be enqueued with the done flag set, the
3624    /// appropriate error code and a NULL data object.
3625    ///
3626    /// An invocation of the I/O handler with the done flag set, an error code of
3627    /// zero and an empty data object indicates that EOF was reached.
3628    ///
3629    ///
3630    /// Parameter `channel`: The dispatch I/O channel from which to read the data.
3631    ///
3632    /// Parameter `offset`: The offset relative to the channel position from which
3633    /// to start reading (only for DISPATCH_IO_RANDOM).
3634    ///
3635    /// Parameter `length`: The length of data to read from the I/O channel, or
3636    /// SIZE_MAX to indicate that data should be read until EOF
3637    /// is reached.
3638    ///
3639    /// Parameter `queue`: The dispatch queue to which the I/O handler should be
3640    /// submitted.
3641    ///
3642    /// Parameter `io_handler`: The I/O handler to enqueue when data is ready to be
3643    /// delivered.
3644    /// param done    A flag indicating whether the operation is complete.
3645    /// param data    An object with the data most recently read from the
3646    /// I/O channel as part of this read operation, or NULL.
3647    /// param error    An errno condition for the read operation or zero if
3648    /// the read was successful.
3649    #[doc(alias = "dispatch_io_read")]
3650    #[cfg(all(feature = "block2", feature = "libc"))]
3651    #[inline]
3652    pub unsafe fn read(
3653        self: &DispatchIO,
3654        offset: libc::off_t,
3655        length: usize,
3656        queue: &DispatchQueue,
3657        io_handler: dispatch_io_handler_t,
3658    ) {
3659        extern "C" {
3660            fn dispatch_io_read(
3661                channel: &DispatchIO,
3662                offset: libc::off_t,
3663                length: usize,
3664                queue: &DispatchQueue,
3665                io_handler: dispatch_io_handler_t,
3666            );
3667        }
3668        unsafe { dispatch_io_read(self, offset, length, queue, io_handler) }
3669    }
3670
3671    /// Schedule a write operation for asynchronous execution on the specified I/O
3672    /// channel. The I/O handler is enqueued one or more times depending on the
3673    /// general load of the system and the policy specified on the I/O channel.
3674    ///
3675    /// Any data remaining to be written to the I/O channel is described by the
3676    /// dispatch data object passed to the I/O handler. This object will be
3677    /// automatically released by the system when the I/O handler returns. It is the
3678    /// responsibility of the application to retain, concatenate or copy the data
3679    /// object if it is needed after the I/O handler returns.
3680    ///
3681    /// Dispatch I/O handlers are not reentrant. The system will ensure that no new
3682    /// I/O handler instance is invoked until the previously enqueued handler block
3683    /// has returned.
3684    ///
3685    /// An invocation of the I/O handler with the done flag set indicates that the
3686    /// write operation is complete and that the handler will not be enqueued again.
3687    ///
3688    /// If an unrecoverable error occurs on the I/O channel's underlying file
3689    /// descriptor, the I/O handler will be enqueued with the done flag set, the
3690    /// appropriate error code and an object containing the data that could not be
3691    /// written.
3692    ///
3693    /// An invocation of the I/O handler with the done flag set and an error code of
3694    /// zero indicates that the data was fully written to the channel.
3695    ///
3696    ///
3697    /// Parameter `channel`: The dispatch I/O channel on which to write the data.
3698    ///
3699    /// Parameter `offset`: The offset relative to the channel position from which
3700    /// to start writing (only for DISPATCH_IO_RANDOM).
3701    ///
3702    /// Parameter `data`: The data to write to the I/O channel. The data object
3703    /// will be retained by the system until the write operation
3704    /// is complete.
3705    ///
3706    /// Parameter `queue`: The dispatch queue to which the I/O handler should be
3707    /// submitted.
3708    ///
3709    /// Parameter `io_handler`: The I/O handler to enqueue when data has been delivered.
3710    /// param done    A flag indicating whether the operation is complete.
3711    /// param data    An object of the data remaining to be
3712    /// written to the I/O channel as part of this write
3713    /// operation, or NULL.
3714    /// param error    An errno condition for the write operation or zero
3715    /// if the write was successful.
3716    #[doc(alias = "dispatch_io_write")]
3717    #[cfg(all(feature = "block2", feature = "libc"))]
3718    #[inline]
3719    pub unsafe fn write(
3720        self: &DispatchIO,
3721        offset: libc::off_t,
3722        data: &DispatchData,
3723        queue: &DispatchQueue,
3724        io_handler: dispatch_io_handler_t,
3725    ) {
3726        extern "C" {
3727            fn dispatch_io_write(
3728                channel: &DispatchIO,
3729                offset: libc::off_t,
3730                data: &DispatchData,
3731                queue: &DispatchQueue,
3732                io_handler: dispatch_io_handler_t,
3733            );
3734        }
3735        unsafe { dispatch_io_write(self, offset, data, queue, io_handler) }
3736    }
3737
3738    /// Close the specified I/O channel to new read or write operations; scheduling
3739    /// operations on a closed channel results in their handler returning an error.
3740    ///
3741    /// If the DISPATCH_IO_STOP flag is provided, the system will make a best effort
3742    /// to interrupt any outstanding read and write operations on the I/O channel,
3743    /// otherwise those operations will run to completion normally.
3744    /// Partial results of read and write operations may be returned even after a
3745    /// channel is closed with the DISPATCH_IO_STOP flag.
3746    /// The final invocation of an I/O handler of an interrupted operation will be
3747    /// passed an ECANCELED error code, as will the I/O handler of an operation
3748    /// scheduled on a closed channel.
3749    ///
3750    ///
3751    /// Parameter `channel`: The dispatch I/O channel to close.
3752    ///
3753    /// Parameter `flags`: The flags for the close operation.
3754    #[doc(alias = "dispatch_io_close")]
3755    #[inline]
3756    pub fn close(self: &DispatchIO, flags: DispatchIOCloseFlags) {
3757        extern "C" {
3758            fn dispatch_io_close(channel: &DispatchIO, flags: DispatchIOCloseFlags);
3759        }
3760        unsafe { dispatch_io_close(self, flags) }
3761    }
3762
3763    /// Schedule a barrier operation on the specified I/O channel; all previously
3764    /// scheduled operations on the channel will complete before the provided
3765    /// barrier block is enqueued onto the global queue determined by the channel's
3766    /// target queue, and no subsequently scheduled operations will start until the
3767    /// barrier block has returned.
3768    ///
3769    /// If multiple channels are associated with the same file descriptor, a barrier
3770    /// operation scheduled on any of these channels will act as a barrier across all
3771    /// channels in question, i.e. all previously scheduled operations on any of the
3772    /// channels will complete before the barrier block is enqueued, and no
3773    /// operations subsequently scheduled on any of the channels will start until the
3774    /// barrier block has returned.
3775    ///
3776    /// While the barrier block is running, it may safely operate on the channel's
3777    /// underlying file descriptor with fsync(2), lseek(2) etc. (but not close(2)).
3778    ///
3779    ///
3780    /// Parameter `channel`: The dispatch I/O channel to schedule the barrier on.
3781    ///
3782    /// Parameter `barrier`: The barrier block.
3783    #[doc(alias = "dispatch_io_barrier")]
3784    #[cfg(feature = "block2")]
3785    #[inline]
3786    pub unsafe fn barrier(self: &DispatchIO, barrier: dispatch_block_t) {
3787        extern "C" {
3788            fn dispatch_io_barrier(channel: &DispatchIO, barrier: dispatch_block_t);
3789        }
3790        unsafe { dispatch_io_barrier(self, barrier) }
3791    }
3792
3793    /// Returns the file descriptor underlying a dispatch I/O channel.
3794    ///
3795    /// Will return -1 for a channel closed with dispatch_io_close() and for a
3796    /// channel associated with a path name that has not yet been open(2)ed.
3797    ///
3798    /// If called from a barrier block scheduled on a channel associated with a path
3799    /// name that has not yet been open(2)ed, this will trigger the channel open(2)
3800    /// operation and return the resulting file descriptor.
3801    ///
3802    ///
3803    /// Parameter `channel`: The dispatch I/O channel to query.
3804    ///
3805    /// Returns: The file descriptor underlying the channel, or -1.
3806    #[doc(alias = "dispatch_io_get_descriptor")]
3807    #[must_use]
3808    #[inline]
3809    pub fn descriptor(self: &DispatchIO) -> dispatch_fd_t {
3810        extern "C" {
3811            fn dispatch_io_get_descriptor(channel: &DispatchIO) -> dispatch_fd_t;
3812        }
3813        unsafe { dispatch_io_get_descriptor(self) }
3814    }
3815
3816    /// Set a high water mark on the I/O channel for all operations.
3817    ///
3818    /// The system will make a best effort to enqueue I/O handlers with partial
3819    /// results as soon the number of bytes processed by an operation (i.e. read or
3820    /// written) reaches the high water mark.
3821    ///
3822    /// The size of data objects passed to I/O handlers for this channel will never
3823    /// exceed the specified high water mark.
3824    ///
3825    /// The default value for the high water mark is unlimited (i.e. SIZE_MAX).
3826    ///
3827    ///
3828    /// Parameter `channel`: The dispatch I/O channel on which to set the policy.
3829    ///
3830    /// Parameter `high_water`: The number of bytes to use as a high water mark.
3831    #[doc(alias = "dispatch_io_set_high_water")]
3832    #[inline]
3833    pub fn set_high_water(self: &DispatchIO, high_water: usize) {
3834        extern "C" {
3835            fn dispatch_io_set_high_water(channel: &DispatchIO, high_water: usize);
3836        }
3837        unsafe { dispatch_io_set_high_water(self, high_water) }
3838    }
3839
3840    /// Set a low water mark on the I/O channel for all operations.
3841    ///
3842    /// The system will process (i.e. read or write) at least the low water mark
3843    /// number of bytes for an operation before enqueueing I/O handlers with partial
3844    /// results.
3845    ///
3846    /// The size of data objects passed to intermediate I/O handler invocations for
3847    /// this channel (i.e. excluding the final invocation) will never be smaller than
3848    /// the specified low water mark, except if the channel has an interval with the
3849    /// DISPATCH_IO_STRICT_INTERVAL flag set or if EOF or an error was encountered.
3850    ///
3851    /// I/O handlers should be prepared to receive amounts of data significantly
3852    /// larger than the low water mark in general. If an I/O handler requires
3853    /// intermediate results of fixed size, set both the low and and the high water
3854    /// mark to that size.
3855    ///
3856    /// The default value for the low water mark is unspecified, but must be assumed
3857    /// to be such that intermediate handler invocations may occur.
3858    /// If I/O handler invocations with partial results are not desired, set the
3859    /// low water mark to SIZE_MAX.
3860    ///
3861    ///
3862    /// Parameter `channel`: The dispatch I/O channel on which to set the policy.
3863    ///
3864    /// Parameter `low_water`: The number of bytes to use as a low water mark.
3865    #[doc(alias = "dispatch_io_set_low_water")]
3866    #[inline]
3867    pub fn set_low_water(self: &DispatchIO, low_water: usize) {
3868        extern "C" {
3869            fn dispatch_io_set_low_water(channel: &DispatchIO, low_water: usize);
3870        }
3871        unsafe { dispatch_io_set_low_water(self, low_water) }
3872    }
3873
3874    /// Set a nanosecond interval at which I/O handlers are to be enqueued on the
3875    /// I/O channel for all operations.
3876    ///
3877    /// This allows an application to receive periodic feedback on the progress of
3878    /// read and write operations, e.g. for the purposes of displaying progress bars.
3879    ///
3880    /// If the amount of data ready to be delivered to an I/O handler at the interval
3881    /// is inferior to the channel low water mark, the handler will only be enqueued
3882    /// if the DISPATCH_IO_STRICT_INTERVAL flag is set.
3883    ///
3884    /// Note that the system may defer enqueueing interval I/O handlers by a small
3885    /// unspecified amount of leeway in order to align with other system activity for
3886    /// improved system performance or power consumption.
3887    ///
3888    ///
3889    /// Parameter `channel`: The dispatch I/O channel on which to set the policy.
3890    ///
3891    /// Parameter `interval`: The interval in nanoseconds at which delivery of the I/O
3892    /// handler is desired.
3893    ///
3894    /// Parameter `flags`: Flags indicating desired data delivery behavior at
3895    /// interval time.
3896    #[doc(alias = "dispatch_io_set_interval")]
3897    #[inline]
3898    pub fn set_interval(self: &DispatchIO, interval: u64, flags: DispatchIOIntervalFlags) {
3899        extern "C" {
3900            fn dispatch_io_set_interval(
3901                channel: &DispatchIO,
3902                interval: u64,
3903                flags: DispatchIOIntervalFlags,
3904            );
3905        }
3906        unsafe { dispatch_io_set_interval(self, interval, flags) }
3907    }
3908}
3909
3910impl DispatchWorkloop {
3911    /// Creates a new dispatch workloop to which workitems may be submitted.
3912    ///
3913    ///
3914    /// Parameter `label`: A string label to attach to the workloop.
3915    ///
3916    ///
3917    /// Returns: The newly created dispatch workloop.
3918    #[doc(alias = "dispatch_workloop_create")]
3919    #[must_use]
3920    #[inline]
3921    pub(crate) unsafe fn __new(label: *const c_char) -> DispatchRetained<DispatchWorkloop> {
3922        extern "C" {
3923            fn dispatch_workloop_create(label: *const c_char) -> Option<NonNull<DispatchWorkloop>>;
3924        }
3925        let ret = unsafe { dispatch_workloop_create(label) };
3926        let ret =
3927            ret.expect("function was marked as returning non-null, but actually returned NULL");
3928        unsafe { DispatchRetained::from_raw(ret) }
3929    }
3930
3931    /// Creates a new inactive dispatch workloop that can be setup and then
3932    /// activated.
3933    ///
3934    ///
3935    /// Creating an inactive workloop allows for it to receive further configuration
3936    /// before it is activated, and workitems can be submitted to it.
3937    ///
3938    /// Submitting workitems to an inactive workloop is undefined and will cause the
3939    /// process to be terminated.
3940    ///
3941    ///
3942    /// Parameter `label`: A string label to attach to the workloop.
3943    ///
3944    ///
3945    /// Returns: The newly created dispatch workloop.
3946    #[doc(alias = "dispatch_workloop_create_inactive")]
3947    #[must_use]
3948    #[inline]
3949    pub(crate) unsafe fn __new_inactive(
3950        label: *const c_char,
3951    ) -> DispatchRetained<DispatchWorkloop> {
3952        extern "C" {
3953            fn dispatch_workloop_create_inactive(
3954                label: *const c_char,
3955            ) -> Option<NonNull<DispatchWorkloop>>;
3956        }
3957        let ret = unsafe { dispatch_workloop_create_inactive(label) };
3958        let ret =
3959            ret.expect("function was marked as returning non-null, but actually returned NULL");
3960        unsafe { DispatchRetained::from_raw(ret) }
3961    }
3962
3963    /// Sets the autorelease frequency of the workloop.
3964    ///
3965    ///
3966    /// See dispatch_queue_attr_make_with_autorelease_frequency().
3967    /// The default policy for a workloop is
3968    /// DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM.
3969    ///
3970    ///
3971    /// Parameter `workloop`: The dispatch workloop to modify.
3972    ///
3973    /// This workloop must be inactive, passing an activated object is undefined
3974    /// and will cause the process to be terminated.
3975    ///
3976    ///
3977    /// Parameter `frequency`: The requested autorelease frequency.
3978    #[doc(alias = "dispatch_workloop_set_autorelease_frequency")]
3979    #[inline]
3980    pub fn set_autorelease_frequency(
3981        self: &DispatchWorkloop,
3982        frequency: DispatchAutoReleaseFrequency,
3983    ) {
3984        extern "C" {
3985            fn dispatch_workloop_set_autorelease_frequency(
3986                workloop: &DispatchWorkloop,
3987                frequency: DispatchAutoReleaseFrequency,
3988            );
3989        }
3990        unsafe { dispatch_workloop_set_autorelease_frequency(self, frequency) }
3991    }
3992}