2 * Copyright (c) 2008-2009 Apple Inc. All rights reserved.
4 * @APPLE_APACHE_LICENSE_HEADER_START@
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * @APPLE_APACHE_LICENSE_HEADER_END@
21 #ifndef __DISPATCH_SOURCE__
22 #define __DISPATCH_SOURCE__
24 #ifndef __DISPATCH_INDIRECT__
25 #error "Please #include <dispatch/dispatch.h> instead of this file directly."
26 #include <dispatch/base.h> // for HeaderDoc
30 #include <mach/port.h>
31 #include <mach/message.h>
33 #include <sys/signal.h>
37 * The dispatch framework provides a suite of interfaces for monitoring low-
38 * level system objects (file descriptors, Mach ports, signals, VFS nodes, etc.)
39 * for activity and automatically submitting event handler blocks to dispatch
40 * queues when such activity occurs.
42 * This suite of interfaces is known as the Dispatch Source API.
46 * @typedef dispatch_source_t
49 * Dispatch sources are used to automatically submit event handler blocks to
50 * dispatch queues in response to external events.
52 DISPATCH_DECL(dispatch_source);
55 * @typedef dispatch_source_type_t
58 * Constants of this type represent the class of low-level system object that
59 * is being monitored by the dispatch source. Constants of this type are
60 * passed as a parameter to dispatch_source_create() and determine how the
61 * handle argument is interpreted (i.e. as a file descriptor, mach port,
62 * signal number, process identifer, etc.), and how the mask arugment is
65 typedef const struct dispatch_source_type_s *dispatch_source_type_t;
68 * @const DISPATCH_SOURCE_TYPE_DATA_ADD
69 * @discussion A dispatch source that coalesces data obtained via calls to
70 * dispatch_source_merge_data(). An ADD is used to coalesce the data.
71 * The handle is unused (pass zero for now).
72 * The mask is unused (pass zero for now).
74 #define DISPATCH_SOURCE_TYPE_DATA_ADD (&_dispatch_source_type_data_add)
75 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
77 const struct dispatch_source_type_s _dispatch_source_type_data_add;
80 * @const DISPATCH_SOURCE_TYPE_DATA_OR
81 * @discussion A dispatch source that coalesces data obtained via calls to
82 * dispatch_source_merge_data(). A logical OR is used to coalesce the data.
83 * The handle is unused (pass zero for now).
84 * The mask is used to perform a logical AND with the value passed to
85 * dispatch_source_merge_data().
87 #define DISPATCH_SOURCE_TYPE_DATA_OR (&_dispatch_source_type_data_or)
88 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
90 const struct dispatch_source_type_s _dispatch_source_type_data_or;
93 * @const DISPATCH_SOURCE_TYPE_MACH_SEND
94 * @discussion A dispatch source that monitors a Mach port for dead name
95 * notifications (send right no longer has any corresponding receive right).
96 * The handle is a Mach port with a send or send-once right (mach_port_t).
97 * The mask is a mask of desired events from dispatch_source_mach_send_flags_t.
99 #define DISPATCH_SOURCE_TYPE_MACH_SEND (&_dispatch_source_type_mach_send)
100 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
102 const struct dispatch_source_type_s _dispatch_source_type_mach_send;
105 * @const DISPATCH_SOURCE_TYPE_MACH_RECV
106 * @discussion A dispatch source that monitors a Mach port for pending messages.
107 * The handle is a Mach port with a receive right (mach_port_t).
108 * The mask is unused (pass zero for now).
110 #define DISPATCH_SOURCE_TYPE_MACH_RECV (&_dispatch_source_type_mach_recv)
111 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
113 const struct dispatch_source_type_s _dispatch_source_type_mach_recv;
116 * @const DISPATCH_SOURCE_TYPE_PROC
117 * @discussion A dispatch source that monitors an external process for events
118 * defined by dispatch_source_proc_flags_t.
119 * The handle is a process identifier (pid_t).
120 * The mask is a mask of desired events from dispatch_source_proc_flags_t.
122 #define DISPATCH_SOURCE_TYPE_PROC (&_dispatch_source_type_proc)
123 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
125 const struct dispatch_source_type_s _dispatch_source_type_proc;
128 * @const DISPATCH_SOURCE_TYPE_READ
129 * @discussion A dispatch source that monitors a file descriptor for pending
130 * bytes available to be read.
131 * The handle is a file descriptor (int).
132 * The mask is unused (pass zero for now).
134 #define DISPATCH_SOURCE_TYPE_READ (&_dispatch_source_type_read)
135 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
137 const struct dispatch_source_type_s _dispatch_source_type_read;
140 * @const DISPATCH_SOURCE_TYPE_SIGNAL
141 * @discussion A dispatch source that monitors the current process for signals.
142 * The handle is a signal number (int).
143 * The mask is unused (pass zero for now).
145 #define DISPATCH_SOURCE_TYPE_SIGNAL (&_dispatch_source_type_signal)
146 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
148 const struct dispatch_source_type_s _dispatch_source_type_signal;
151 * @const DISPATCH_SOURCE_TYPE_TIMER
152 * @discussion A dispatch source that submits the event handler block based
154 * The handle is unused (pass zero for now).
155 * The mask is unused (pass zero for now).
157 #define DISPATCH_SOURCE_TYPE_TIMER (&_dispatch_source_type_timer)
158 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
160 const struct dispatch_source_type_s _dispatch_source_type_timer;
163 * @const DISPATCH_SOURCE_TYPE_VNODE
164 * @discussion A dispatch source that monitors a file descriptor for events
165 * defined by dispatch_source_vnode_flags_t.
166 * The handle is a file descriptor (int).
167 * The mask is a mask of desired events from dispatch_source_vnode_flags_t.
169 #define DISPATCH_SOURCE_TYPE_VNODE (&_dispatch_source_type_vnode)
170 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
172 const struct dispatch_source_type_s _dispatch_source_type_vnode;
175 * @const DISPATCH_SOURCE_TYPE_WRITE
176 * @discussion A dispatch source that monitors a file descriptor for available
177 * buffer space to write bytes.
178 * The handle is a file descriptor (int).
179 * The mask is unused (pass zero for now).
181 #define DISPATCH_SOURCE_TYPE_WRITE (&_dispatch_source_type_write)
182 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
184 const struct dispatch_source_type_s _dispatch_source_type_write;
187 * @enum dispatch_source_mach_send_flags_t
189 * @constant DISPATCH_MACH_SEND_DEAD
190 * The receive right corresponding to the given send right was destroyed.
193 DISPATCH_MACH_SEND_DEAD = 0x1,
197 * @enum dispatch_source_proc_flags_t
199 * @constant DISPATCH_PROC_EXIT
200 * The process has exited (perhaps cleanly, perhaps not).
202 * @constant DISPATCH_PROC_FORK
203 * The process has created one or more child processes.
205 * @constant DISPATCH_PROC_EXEC
206 * The process has become another executable image via
207 * exec*() or posix_spawn*().
209 * @constant DISPATCH_PROC_SIGNAL
210 * A Unix signal was delivered to the process.
213 DISPATCH_PROC_EXIT = 0x80000000,
214 DISPATCH_PROC_FORK = 0x40000000,
215 DISPATCH_PROC_EXEC = 0x20000000,
216 DISPATCH_PROC_SIGNAL = 0x08000000,
220 * @enum dispatch_source_vnode_flags_t
222 * @constant DISPATCH_VNODE_DELETE
223 * The filesystem object was deleted from the namespace.
225 * @constant DISPATCH_VNODE_WRITE
226 * The filesystem object data changed.
228 * @constant DISPATCH_VNODE_EXTEND
229 * The filesystem object changed in size.
231 * @constant DISPATCH_VNODE_ATTRIB
232 * The filesystem object metadata changed.
234 * @constant DISPATCH_VNODE_LINK
235 * The filesystem object link count changed.
237 * @constant DISPATCH_VNODE_RENAME
238 * The filesystem object was renamed in the namespace.
240 * @constant DISPATCH_VNODE_REVOKE
241 * The filesystem object was revoked.
244 DISPATCH_VNODE_DELETE = 0x1,
245 DISPATCH_VNODE_WRITE = 0x2,
246 DISPATCH_VNODE_EXTEND = 0x4,
247 DISPATCH_VNODE_ATTRIB = 0x8,
248 DISPATCH_VNODE_LINK = 0x10,
249 DISPATCH_VNODE_RENAME = 0x20,
250 DISPATCH_VNODE_REVOKE = 0x40,
253 __DISPATCH_BEGIN_DECLS
256 * @function dispatch_source_create
259 * Creates a new dispatch source to monitor low-level system objects and auto-
260 * matically submit a handler block to a dispatch queue in response to events.
263 * Dispatch sources are not reentrant. Any events received while the dispatch
264 * source is suspended or while the event handler block is currently executing
265 * will be coalesced and delivered after the dispatch source is resumed or the
266 * event handler block has returned.
268 * Dispatch sources are created in a suspended state. After creating the
269 * source and setting any desired attributes (i.e. the handler, context, etc.),
270 * a call must be made to dispatch_resume() in order to begin event delivery.
273 * Declares the type of the dispatch source. Must be one of the defined
274 * dispatch_source_type_t constants.
276 * The underlying system handle to monitor. The interpretation of this argument
277 * is determined by the constant provided in the type parameter.
279 * A mask of flags specifying which events are desired. The interpretation of
280 * this argument is determined by the constant provided in the type parameter.
282 * The dispatch queue to which the event handler block will be submited.
284 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
285 DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_NOTHROW
287 dispatch_source_create(dispatch_source_type_t type,
290 dispatch_queue_t queue);
293 * @function dispatch_source_set_event_handler
296 * Sets the event handler block for the given dispatch source.
299 * The dispatch source to modify.
300 * The result of passing NULL in this parameter is undefined.
303 * The event handler block to submit to the source's target queue.
306 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
307 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
309 dispatch_source_set_event_handler(dispatch_source_t source,
310 dispatch_block_t handler);
311 #endif /* __BLOCKS__ */
314 * @function dispatch_source_set_event_handler_f
317 * Sets the event handler function for the given dispatch source.
320 * The dispatch source to modify.
321 * The result of passing NULL in this parameter is undefined.
324 * The event handler function to submit to the source's target queue.
325 * The context parameter passed to the event handler function is the current
326 * context of the dispatch source at the time the handler call is made.
327 * The result of passing NULL in this parameter is undefined.
329 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
330 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
332 dispatch_source_set_event_handler_f(dispatch_source_t source,
333 dispatch_function_t handler);
336 * @function dispatch_source_set_cancel_handler
339 * Sets the cancellation handler block for the given dispatch source.
342 * The cancellation handler (if specified) will be submitted to the source's
343 * target queue in response to a call to dispatch_source_cancel() once the
344 * system has released all references to the source's underlying handle and
345 * the source's event handler block has returned.
348 * A cancellation handler is required for file descriptor and mach port based
349 * sources in order to safely close the descriptor or destroy the port. Closing
350 * the descriptor or port before the cancellation handler may result in a race
351 * condition. If a new descriptor is allocated with the same value as the
352 * recently closed descriptor while the source's event handler is still running,
353 * the event handler may read/write data to the wrong descriptor.
356 * The dispatch source to modify.
357 * The result of passing NULL in this parameter is undefined.
360 * The cancellation handler block to submit to the source's target queue.
363 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
364 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
366 dispatch_source_set_cancel_handler(dispatch_source_t source,
367 dispatch_block_t cancel_handler);
368 #endif /* __BLOCKS__ */
371 * @function dispatch_source_set_cancel_handler_f
374 * Sets the cancellation handler function for the given dispatch source.
377 * See dispatch_source_set_cancel_handler() for more details.
380 * The dispatch source to modify.
381 * The result of passing NULL in this parameter is undefined.
384 * The cancellation handler function to submit to the source's target queue.
385 * The context parameter passed to the event handler function is the current
386 * context of the dispatch source at the time the handler call is made.
388 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
389 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
391 dispatch_source_set_cancel_handler_f(dispatch_source_t source,
392 dispatch_function_t cancel_handler);
395 * @function dispatch_source_cancel
398 * Asynchronously cancel the dispatch source, preventing any further invocation
399 * of its event handler block.
402 * Cancellation prevents any further invocation of the event handler block for
403 * the specified dispatch source, but does not interrupt an event handler
404 * block that is already in progress.
406 * The cancellation handler is submitted to the source's target queue once the
407 * the source's event handler has finished, indicating it is now safe to close
408 * the source's handle (i.e. file descriptor or mach port).
410 * See dispatch_source_set_cancel_handler() for more information.
413 * The dispatch source to be canceled.
414 * The result of passing NULL in this parameter is undefined.
416 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
417 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
419 dispatch_source_cancel(dispatch_source_t source);
422 * @function dispatch_source_testcancel
425 * Tests whether the given dispatch source has been canceled.
428 * The dispatch source to be tested.
429 * The result of passing NULL in this parameter is undefined.
432 * Non-zero if canceled and zero if not canceled.
434 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
435 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
437 dispatch_source_testcancel(dispatch_source_t source);
440 * @function dispatch_source_get_handle
443 * Returns the underlying system handle associated with this dispatch source.
446 * The result of passing NULL in this parameter is undefined.
449 * The return value should be interpreted according to the type of the dispatch
450 * source, and may be one of the following handles:
452 * DISPATCH_SOURCE_TYPE_DATA_ADD: n/a
453 * DISPATCH_SOURCE_TYPE_DATA_OR: n/a
454 * DISPATCH_SOURCE_TYPE_MACH_SEND: mach port (mach_port_t)
455 * DISPATCH_SOURCE_TYPE_MACH_RECV: mach port (mach_port_t)
456 * DISPATCH_SOURCE_TYPE_PROC: process identifier (pid_t)
457 * DISPATCH_SOURCE_TYPE_READ: file descriptor (int)
458 * DISPATCH_SOURCE_TYPE_SIGNAL: signal number (int)
459 * DISPATCH_SOURCE_TYPE_TIMER: n/a
460 * DISPATCH_SOURCE_TYPE_VNODE: file descriptor (int)
461 * DISPATCH_SOURCE_TYPE_WRITE: file descriptor (int)
463 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
464 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_PURE DISPATCH_NOTHROW
466 dispatch_source_get_handle(dispatch_source_t source);
469 * @function dispatch_source_get_mask
472 * Returns the mask of events monitored by the dispatch source.
475 * The result of passing NULL in this parameter is undefined.
478 * The return value should be interpreted according to the type of the dispatch
479 * source, and may be one of the following flag sets:
481 * DISPATCH_SOURCE_TYPE_DATA_ADD: n/a
482 * DISPATCH_SOURCE_TYPE_DATA_OR: n/a
483 * DISPATCH_SOURCE_TYPE_MACH_SEND: dispatch_source_mach_send_flags_t
484 * DISPATCH_SOURCE_TYPE_MACH_RECV: n/a
485 * DISPATCH_SOURCE_TYPE_PROC: dispatch_source_proc_flags_t
486 * DISPATCH_SOURCE_TYPE_READ: n/a
487 * DISPATCH_SOURCE_TYPE_SIGNAL: n/a
488 * DISPATCH_SOURCE_TYPE_TIMER: n/a
489 * DISPATCH_SOURCE_TYPE_VNODE: dispatch_source_vnode_flags_t
490 * DISPATCH_SOURCE_TYPE_WRITE: n/a
492 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
493 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_PURE DISPATCH_NOTHROW
495 dispatch_source_get_mask(dispatch_source_t source);
498 * @function dispatch_source_get_data
501 * Returns pending data for the dispatch source.
504 * This function is intended to be called from within the event handler block.
505 * The result of calling this function outside of the event handler callback is
509 * The result of passing NULL in this parameter is undefined.
512 * The return value should be interpreted according to the type of the dispatch
513 * source, and may be one of the following:
515 * DISPATCH_SOURCE_TYPE_DATA_ADD: application defined data
516 * DISPATCH_SOURCE_TYPE_DATA_OR: application defined data
517 * DISPATCH_SOURCE_TYPE_MACH_SEND: dispatch_source_mach_send_flags_t
518 * DISPATCH_SOURCE_TYPE_MACH_RECV: n/a
519 * DISPATCH_SOURCE_TYPE_PROC: dispatch_source_proc_flags_t
520 * DISPATCH_SOURCE_TYPE_READ: estimated bytes available to read
521 * DISPATCH_SOURCE_TYPE_SIGNAL: number of signals delivered since
522 * the last handler invocation
523 * DISPATCH_SOURCE_TYPE_TIMER: number of times the timer has fired
524 * since the last handler invocation
525 * DISPATCH_SOURCE_TYPE_VNODE: dispatch_source_vnode_flags_t
526 * DISPATCH_SOURCE_TYPE_WRITE: estimated buffer space available
528 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
529 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_PURE DISPATCH_NOTHROW
531 dispatch_source_get_data(dispatch_source_t source);
534 * @function dispatch_source_merge_data
537 * Merges data into a dispatch source of type DISPATCH_SOURCE_TYPE_DATA_ADD or
538 * DISPATCH_SOURCE_TYPE_DATA_OR and submits its event handler block to its
542 * The result of passing NULL in this parameter is undefined.
545 * The value to coalesce with the pending data using a logical OR or an ADD
546 * as specified by the dispatch source type. A value of zero has no effect
547 * and will not result in the submission of the event handler block.
549 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
550 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
552 dispatch_source_merge_data(dispatch_source_t source, unsigned long value);
555 * @function dispatch_source_set_timer
558 * Sets a start time, interval, and leeway value for a timer source.
561 * Calling this function has no effect if the timer source has already been
564 * The start time argument also determines which clock will be used for the
565 * timer. If the start time is DISPATCH_TIME_NOW or created with
566 * dispatch_time() then the timer is based on mach_absolute_time(). Otherwise,
567 * if the start time of the timer is created with dispatch_walltime() then the
568 * timer is based on gettimeofday(3).
571 * The start time of the timer. See dispatch_time() and dispatch_walltime()
572 * for more information.
575 * The nanosecond interval for the timer.
578 * A hint given to the system by the application for the amount of leeway, in
579 * nanoseconds, that the system may defer the timer in order to align with other
580 * system activity for improved system performance or power consumption. (For
581 * example, an application might perform a periodic task every 5 minutes, with
582 * a leeway of up to 30 seconds.) Note that some latency is to be expected for
583 * all timers even when a leeway value of zero is specified.
585 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
586 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
588 dispatch_source_set_timer(dispatch_source_t source,
589 dispatch_time_t start,