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}