]> git.saurik.com Git - apple/libdispatch.git/blob - src/source.h
libdispatch-84.5.tar.gz
[apple/libdispatch.git] / src / source.h
1 /*
2 * Copyright (c) 2008-2009 Apple Inc. All rights reserved.
3 *
4 * @APPLE_APACHE_LICENSE_HEADER_START@
5 *
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
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
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.
17 *
18 * @APPLE_APACHE_LICENSE_HEADER_END@
19 */
20
21 #ifndef __DISPATCH_SOURCE__
22 #define __DISPATCH_SOURCE__
23
24 #ifndef __DISPATCH_INDIRECT__
25 #error "Please #include <dispatch/dispatch.h> instead of this file directly."
26 #include <dispatch/base.h> // for HeaderDoc
27 #endif
28
29 #include <mach/port.h>
30 #include <mach/message.h>
31 #include <sys/signal.h>
32
33 /*!
34 * @header
35 * The dispatch framework provides a suite of interfaces for monitoring low-
36 * level system objects (file descriptors, Mach ports, signals, VFS nodes, etc.)
37 * for activity and automatically submitting event handler blocks to dispatch
38 * queues when such activity occurs.
39 *
40 * This suite of interfaces is known as the Dispatch Source API.
41 */
42
43 /*!
44 * @typedef dispatch_source_t
45 *
46 * @abstract
47 * Dispatch sources are used to automatically submit event handler blocks to
48 * dispatch queues in response to external events.
49 */
50 DISPATCH_DECL(dispatch_source);
51
52 /*!
53 * @typedef dispatch_source_type_t
54 *
55 * @abstract
56 * Constants of this type represent the class of low-level system object that
57 * is being monitored by the dispatch source. Constants of this type are
58 * passed as a parameter to dispatch_source_create() and determine how the
59 * handle argument is interpreted (i.e. as a file descriptor, mach port,
60 * signal number, process identifer, etc.), and how the mask arugment is
61 * interpreted.
62 */
63 typedef const struct dispatch_source_type_s *dispatch_source_type_t;
64
65 /*!
66 * @const DISPATCH_SOURCE_TYPE_DATA_ADD
67 * @discussion A dispatch source that coalesces data obtained via calls to
68 * dispatch_source_merge_data(). An ADD is used to coalesce the data.
69 * The handle is unused (pass zero for now).
70 * The mask is unused (pass zero for now).
71 */
72 #define DISPATCH_SOURCE_TYPE_DATA_ADD (&_dispatch_source_type_data_add)
73 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
74 extern const struct dispatch_source_type_s _dispatch_source_type_data_add;
75
76 /*!
77 * @const DISPATCH_SOURCE_TYPE_DATA_OR
78 * @discussion A dispatch source that coalesces data obtained via calls to
79 * dispatch_source_merge_data(). A logical OR is used to coalesce the data.
80 * The handle is unused (pass zero for now).
81 * The mask is used to perform a logical AND with the value passed to
82 * dispatch_source_merge_data().
83 */
84 #define DISPATCH_SOURCE_TYPE_DATA_OR (&_dispatch_source_type_data_or)
85 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
86 extern const struct dispatch_source_type_s _dispatch_source_type_data_or;
87
88 /*!
89 * @const DISPATCH_SOURCE_TYPE_MACH_SEND
90 * @discussion A dispatch source that monitors a Mach port for dead name
91 * notifications (send right no longer has any corresponding receive right).
92 * The handle is a Mach port with a send or send-once right (mach_port_t).
93 * The mask is a mask of desired events from dispatch_source_mach_send_flags_t.
94 */
95 #define DISPATCH_SOURCE_TYPE_MACH_SEND (&_dispatch_source_type_mach_send)
96 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
97 extern const struct dispatch_source_type_s _dispatch_source_type_mach_send;
98
99 /*!
100 * @const DISPATCH_SOURCE_TYPE_MACH_RECV
101 * @discussion A dispatch source that monitors a Mach port for pending messages.
102 * The handle is a Mach port with a receive right (mach_port_t).
103 * The mask is unused (pass zero for now).
104 */
105 #define DISPATCH_SOURCE_TYPE_MACH_RECV (&_dispatch_source_type_mach_recv)
106 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
107 extern const struct dispatch_source_type_s _dispatch_source_type_mach_recv;
108
109 /*!
110 * @const DISPATCH_SOURCE_TYPE_PROC
111 * @discussion A dispatch source that monitors an external process for events
112 * defined by dispatch_source_proc_flags_t.
113 * The handle is a process identifier (pid_t).
114 * The mask is a mask of desired events from dispatch_source_proc_flags_t.
115 */
116 #define DISPATCH_SOURCE_TYPE_PROC (&_dispatch_source_type_proc)
117 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
118 extern const struct dispatch_source_type_s _dispatch_source_type_proc;
119
120 /*!
121 * @const DISPATCH_SOURCE_TYPE_READ
122 * @discussion A dispatch source that monitors a file descriptor for pending
123 * bytes available to be read.
124 * The handle is a file descriptor (int).
125 * The mask is unused (pass zero for now).
126 */
127 #define DISPATCH_SOURCE_TYPE_READ (&_dispatch_source_type_read)
128 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
129 extern const struct dispatch_source_type_s _dispatch_source_type_read;
130
131 /*!
132 * @const DISPATCH_SOURCE_TYPE_SIGNAL
133 * @discussion A dispatch source that monitors the current process for signals.
134 * The handle is a signal number (int).
135 * The mask is unused (pass zero for now).
136 */
137 #define DISPATCH_SOURCE_TYPE_SIGNAL (&_dispatch_source_type_signal)
138 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
139 extern const struct dispatch_source_type_s _dispatch_source_type_signal;
140
141 /*!
142 * @const DISPATCH_SOURCE_TYPE_TIMER
143 * @discussion A dispatch source that submits the event handler block based
144 * on a timer.
145 * The handle is unused (pass zero for now).
146 * The mask is unused (pass zero for now).
147 */
148 #define DISPATCH_SOURCE_TYPE_TIMER (&_dispatch_source_type_timer)
149 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
150 extern const struct dispatch_source_type_s _dispatch_source_type_timer;
151
152 /*!
153 * @const DISPATCH_SOURCE_TYPE_VNODE
154 * @discussion A dispatch source that monitors a file descriptor for events
155 * defined by dispatch_source_vnode_flags_t.
156 * The handle is a file descriptor (int).
157 * The mask is a mask of desired events from dispatch_source_vnode_flags_t.
158 */
159 #define DISPATCH_SOURCE_TYPE_VNODE (&_dispatch_source_type_vnode)
160 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
161 extern const struct dispatch_source_type_s _dispatch_source_type_vnode;
162
163 /*!
164 * @const DISPATCH_SOURCE_TYPE_WRITE
165 * @discussion A dispatch source that monitors a file descriptor for available
166 * buffer space to write bytes.
167 * The handle is a file descriptor (int).
168 * The mask is unused (pass zero for now).
169 */
170 #define DISPATCH_SOURCE_TYPE_WRITE (&_dispatch_source_type_write)
171 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
172 extern const struct dispatch_source_type_s _dispatch_source_type_write;
173
174 /*!
175 * @enum dispatch_source_mach_send_flags_t
176 *
177 * @constant DISPATCH_MACH_SEND_DEAD
178 * The receive right corresponding to the given send right was destroyed.
179 */
180 enum {
181 DISPATCH_MACH_SEND_DEAD = 0x1,
182 };
183
184 /*!
185 * @enum dispatch_source_proc_flags_t
186 *
187 * @constant DISPATCH_PROC_EXIT
188 * The process has exited (perhaps cleanly, perhaps not).
189 *
190 * @constant DISPATCH_PROC_FORK
191 * The process has created one or more child processes.
192 *
193 * @constant DISPATCH_PROC_EXEC
194 * The process has become another executable image via
195 * exec*() or posix_spawn*().
196 *
197 * @constant DISPATCH_PROC_SIGNAL
198 * A Unix signal was delivered to the process.
199 */
200 enum {
201 DISPATCH_PROC_EXIT = 0x80000000,
202 DISPATCH_PROC_FORK = 0x40000000,
203 DISPATCH_PROC_EXEC = 0x20000000,
204 DISPATCH_PROC_SIGNAL = 0x08000000,
205 };
206
207 /*!
208 * @enum dispatch_source_vnode_flags_t
209 *
210 * @constant DISPATCH_VNODE_DELETE
211 * The filesystem object was deleted from the namespace.
212 *
213 * @constant DISPATCH_VNODE_WRITE
214 * The filesystem object data changed.
215 *
216 * @constant DISPATCH_VNODE_EXTEND
217 * The filesystem object changed in size.
218 *
219 * @constant DISPATCH_VNODE_ATTRIB
220 * The filesystem object metadata changed.
221 *
222 * @constant DISPATCH_VNODE_LINK
223 * The filesystem object link count changed.
224 *
225 * @constant DISPATCH_VNODE_RENAME
226 * The filesystem object was renamed in the namespace.
227 *
228 * @constant DISPATCH_VNODE_REVOKE
229 * The filesystem object was revoked.
230 */
231 enum {
232 DISPATCH_VNODE_DELETE = 0x1,
233 DISPATCH_VNODE_WRITE = 0x2,
234 DISPATCH_VNODE_EXTEND = 0x4,
235 DISPATCH_VNODE_ATTRIB = 0x8,
236 DISPATCH_VNODE_LINK = 0x10,
237 DISPATCH_VNODE_RENAME = 0x20,
238 DISPATCH_VNODE_REVOKE = 0x40,
239 };
240
241 __BEGIN_DECLS
242
243 /*!
244 * @function dispatch_source_create
245 *
246 * @abstract
247 * Creates a new dispatch source to monitor low-level system objects and auto-
248 * matically submit a handler block to a dispatch queue in response to events.
249 *
250 * @discussion
251 * Dispatch sources are not reentrant. Any events received while the dispatch
252 * source is suspended or while the event handler block is currently executing
253 * will be coalesced and delivered after the dispatch source is resumed or the
254 * event handler block has returned.
255 *
256 * Dispatch sources are created in a suspended state. After creating the
257 * source and setting any desired attributes (i.e. the handler, context, etc.),
258 * a call must be made to dispatch_resume() in order to begin event delivery.
259 *
260 * @param type
261 * Declares the type of the dispatch source. Must be one of the defined
262 * dispatch_source_type_t constants.
263 * @param handle
264 * The underlying system handle to monitor. The interpretation of this argument
265 * is determined by the constant provided in the type parameter.
266 * @param mask
267 * A mask of flags specifying which events are desired. The interpretation of
268 * this argument is determined by the constant provided in the type parameter.
269 * @param queue
270 * The dispatch queue to which the event handler block will be submited.
271 */
272 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
273 DISPATCH_MALLOC DISPATCH_NOTHROW
274 dispatch_source_t
275 dispatch_source_create(dispatch_source_type_t type,
276 uintptr_t handle,
277 unsigned long mask,
278 dispatch_queue_t queue);
279
280 /*!
281 * @function dispatch_source_set_event_handler
282 *
283 * @abstract
284 * Sets the event handler block for the given dispatch source.
285 *
286 * @param source
287 * The dispatch source to modify.
288 * The result of passing NULL in this parameter is undefined.
289 *
290 * @param handler
291 * The event handler block to submit to the source's target queue.
292 */
293 #ifdef __BLOCKS__
294 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
295 DISPATCH_NONNULL1 DISPATCH_NOTHROW
296 void
297 dispatch_source_set_event_handler(dispatch_source_t source,
298 dispatch_block_t handler);
299 #endif /* __BLOCKS__ */
300
301 /*!
302 * @function dispatch_source_set_event_handler_f
303 *
304 * @abstract
305 * Sets the event handler function for the given dispatch source.
306 *
307 * @param source
308 * The dispatch source to modify.
309 * The result of passing NULL in this parameter is undefined.
310 *
311 * @param handler
312 * The event handler function to submit to the source's target queue.
313 * The context parameter passed to the event handler function is the current
314 * context of the dispatch source at the time the handler call is made.
315 * The result of passing NULL in this parameter is undefined.
316 */
317 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
318 DISPATCH_NONNULL1 DISPATCH_NOTHROW
319 void
320 dispatch_source_set_event_handler_f(dispatch_source_t source,
321 dispatch_function_t handler);
322
323 /*!
324 * @function dispatch_source_set_cancel_handler
325 *
326 * @abstract
327 * Sets the cancellation handler block for the given dispatch source.
328 *
329 * @discussion
330 * The cancellation handler (if specified) will be submitted to the source's
331 * target queue in response to a call to dispatch_source_cancel() once the
332 * system has released all references to the source's underlying handle and
333 * the source's event handler block has returned.
334 *
335 * IMPORTANT:
336 * A cancellation handler is required for file descriptor and mach port based
337 * sources in order to safely close the descriptor or destroy the port. Closing
338 * the descriptor or port before the cancellation handler may result in a race
339 * condition. If a new descriptor is allocated with the same value as the
340 * recently closed descriptor while the source's event handler is still running,
341 * the event handler may read/write data to the wrong descriptor.
342 *
343 * @param source
344 * The dispatch source to modify.
345 * The result of passing NULL in this parameter is undefined.
346 *
347 * @param handler
348 * The cancellation handler block to submit to the source's target queue.
349 */
350 #ifdef __BLOCKS__
351 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
352 DISPATCH_NONNULL1 DISPATCH_NOTHROW
353 void
354 dispatch_source_set_cancel_handler(dispatch_source_t source,
355 dispatch_block_t cancel_handler);
356 #endif /* __BLOCKS__ */
357
358 /*!
359 * @function dispatch_source_set_cancel_handler_f
360 *
361 * @abstract
362 * Sets the cancellation handler function for the given dispatch source.
363 *
364 * @discussion
365 * See dispatch_source_set_cancel_handler() for more details.
366 *
367 * @param source
368 * The dispatch source to modify.
369 * The result of passing NULL in this parameter is undefined.
370 *
371 * @param handler
372 * The cancellation handler function to submit to the source's target queue.
373 * The context parameter passed to the event handler function is the current
374 * context of the dispatch source at the time the handler call is made.
375 */
376 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
377 DISPATCH_NONNULL1 DISPATCH_NOTHROW
378 void
379 dispatch_source_set_cancel_handler_f(dispatch_source_t source,
380 dispatch_function_t cancel_handler);
381
382 /*!
383 * @function dispatch_source_cancel
384 *
385 * @abstract
386 * Asynchronously cancel the dispatch source, preventing any further invocation
387 * of its event handler block.
388 *
389 * @discussion
390 * Cancellation prevents any further invocation of the event handler block for
391 * the specified dispatch source, but does not interrupt an event handler
392 * block that is already in progress.
393 *
394 * The cancellation handler is submitted to the source's target queue once the
395 * the source's event handler has finished, indicating it is now safe to close
396 * the source's handle (i.e. file descriptor or mach port).
397 *
398 * See dispatch_source_set_cancel_handler() for more information.
399 *
400 * @param source
401 * The dispatch source to be canceled.
402 * The result of passing NULL in this parameter is undefined.
403 */
404 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
405 DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
406 void
407 dispatch_source_cancel(dispatch_source_t source);
408
409 /*!
410 * @function dispatch_source_testcancel
411 *
412 * @abstract
413 * Tests whether the given dispatch source has been canceled.
414 *
415 * @param source
416 * The dispatch source to be tested.
417 * The result of passing NULL in this parameter is undefined.
418 *
419 * @result
420 * Non-zero if canceled and zero if not canceled.
421 */
422 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
423 DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
424 long
425 dispatch_source_testcancel(dispatch_source_t source);
426
427 /*!
428 * @function dispatch_source_get_handle
429 *
430 * @abstract
431 * Returns the underlying system handle associated with this dispatch source.
432 *
433 * @param source
434 * The result of passing NULL in this parameter is undefined.
435 *
436 * @result
437 * The return value should be interpreted according to the type of the dispatch
438 * source, and may be one of the following handles:
439 *
440 * DISPATCH_SOURCE_TYPE_DATA_ADD: n/a
441 * DISPATCH_SOURCE_TYPE_DATA_OR: n/a
442 * DISPATCH_SOURCE_TYPE_MACH_SEND: mach port (mach_port_t)
443 * DISPATCH_SOURCE_TYPE_MACH_RECV: mach port (mach_port_t)
444 * DISPATCH_SOURCE_TYPE_PROC: process identifier (pid_t)
445 * DISPATCH_SOURCE_TYPE_READ: file descriptor (int)
446 * DISPATCH_SOURCE_TYPE_SIGNAL: signal number (int)
447 * DISPATCH_SOURCE_TYPE_TIMER: n/a
448 * DISPATCH_SOURCE_TYPE_VNODE: file descriptor (int)
449 * DISPATCH_SOURCE_TYPE_WRITE: file descriptor (int)
450 */
451 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
452 DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_PURE DISPATCH_NOTHROW
453 uintptr_t
454 dispatch_source_get_handle(dispatch_source_t source);
455
456 /*!
457 * @function dispatch_source_get_mask
458 *
459 * @abstract
460 * Returns the mask of events monitored by the dispatch source.
461 *
462 * @param source
463 * The result of passing NULL in this parameter is undefined.
464 *
465 * @result
466 * The return value should be interpreted according to the type of the dispatch
467 * source, and may be one of the following flag sets:
468 *
469 * DISPATCH_SOURCE_TYPE_DATA_ADD: n/a
470 * DISPATCH_SOURCE_TYPE_DATA_OR: n/a
471 * DISPATCH_SOURCE_TYPE_MACH_SEND: dispatch_source_mach_send_flags_t
472 * DISPATCH_SOURCE_TYPE_MACH_RECV: n/a
473 * DISPATCH_SOURCE_TYPE_PROC: dispatch_source_proc_flags_t
474 * DISPATCH_SOURCE_TYPE_READ: n/a
475 * DISPATCH_SOURCE_TYPE_SIGNAL: n/a
476 * DISPATCH_SOURCE_TYPE_TIMER: n/a
477 * DISPATCH_SOURCE_TYPE_VNODE: dispatch_source_vnode_flags_t
478 * DISPATCH_SOURCE_TYPE_WRITE: n/a
479 */
480 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
481 DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_PURE DISPATCH_NOTHROW
482 unsigned long
483 dispatch_source_get_mask(dispatch_source_t source);
484
485 /*!
486 * @function dispatch_source_get_data
487 *
488 * @abstract
489 * Returns pending data for the dispatch source.
490 *
491 * @discussion
492 * This function is intended to be called from within the event handler block.
493 * The result of calling this function outside of the event handler callback is
494 * undefined.
495 *
496 * @param source
497 * The result of passing NULL in this parameter is undefined.
498 *
499 * @result
500 * The return value should be interpreted according to the type of the dispatch
501 * source, and may be one of the following:
502 *
503 * DISPATCH_SOURCE_TYPE_DATA_ADD: application defined data
504 * DISPATCH_SOURCE_TYPE_DATA_OR: application defined data
505 * DISPATCH_SOURCE_TYPE_MACH_SEND: dispatch_source_mach_send_flags_t
506 * DISPATCH_SOURCE_TYPE_MACH_RECV: n/a
507 * DISPATCH_SOURCE_TYPE_PROC: dispatch_source_proc_flags_t
508 * DISPATCH_SOURCE_TYPE_READ: estimated bytes available to read
509 * DISPATCH_SOURCE_TYPE_SIGNAL: number of signals delivered since
510 * the last handler invocation
511 * DISPATCH_SOURCE_TYPE_TIMER: number of times the timer has fired
512 * since the last handler invocation
513 * DISPATCH_SOURCE_TYPE_VNODE: dispatch_source_vnode_flags_t
514 * DISPATCH_SOURCE_TYPE_WRITE: estimated buffer space available
515 */
516 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
517 DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_PURE DISPATCH_NOTHROW
518 unsigned long
519 dispatch_source_get_data(dispatch_source_t source);
520
521 /*!
522 * @function dispatch_source_merge_data
523 *
524 * @abstract
525 * Merges data into a dispatch source of type DISPATCH_SOURCE_TYPE_DATA_ADD or
526 * DISPATCH_SOURCE_TYPE_DATA_OR and submits its event handler block to its
527 * target queue.
528 *
529 * @param source
530 * The result of passing NULL in this parameter is undefined.
531 *
532 * @param value
533 * The value to coalesce with the pending data using a logical OR or an ADD
534 * as specified by the dispatch source type. A value of zero has no effect
535 * and will not result in the submission of the event handler block.
536 */
537 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
538 DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
539 void
540 dispatch_source_merge_data(dispatch_source_t source, unsigned long value);
541
542 /*!
543 * @function dispatch_source_set_timer
544 *
545 * @abstract
546 * Sets a start time, interval, and leeway value for a timer source.
547 *
548 * @discussion
549 * Calling this function has no effect if the timer source has already been
550 * canceled.
551 *
552 * The start time argument also determines which clock will be used for the
553 * timer. If the start time is DISPATCH_TIME_NOW or created with
554 * dispatch_time() then the timer is based on mach_absolute_time(). Otherwise,
555 * if the start time of the timer is created with dispatch_walltime() then the
556 * timer is based on gettimeofday(3).
557 *
558 * @param start
559 * The start time of the timer. See dispatch_time() and dispatch_walltime()
560 * for more information.
561 *
562 * @param interval
563 * The nanosecond interval for the timer.
564 *
565 * @param leeway
566 * A hint given to the system by the application for the amount of leeway, in
567 * nanoseconds, that the system may defer the timer in order to align with other
568 * system activity for improved system performance or power consumption. (For
569 * example, an application might perform a periodic task every 5 minutes, with
570 * a leeway of up to 30 seconds.) Note that some latency is to be expected for
571 * all timers even when a leeway value of zero is specified.
572 */
573 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
574 DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
575 void
576 dispatch_source_set_timer(dispatch_source_t source,
577 dispatch_time_t start,
578 uint64_t interval,
579 uint64_t leeway);
580
581 __END_DECLS
582
583 #endif