1 /*
2  * Copyright (c) 2009-2013 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_IO__
22 #define __DISPATCH_IO__
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 DISPATCH_ASSUME_NONNULL_BEGIN
30 
31 __BEGIN_DECLS
32 
33 /*! @header
34  * Dispatch I/O provides both stream and random access asynchronous read and
35  * write operations on file descriptors. One or more dispatch I/O channels may
36  * be created from a file descriptor as either the DISPATCH_IO_STREAM type or
37  * DISPATCH_IO_RANDOM type. Once a channel has been created the application may
38  * schedule asynchronous read and write operations.
39  *
40  * The application may set policies on the dispatch I/O channel to indicate the
41  * desired frequency of I/O handlers for long-running operations.
42  *
43  * Dispatch I/O also provides a memory management model for I/O buffers that
44  * avoids unnecessary copying of data when pipelined between channels. Dispatch
45  * I/O monitors the overall memory pressure and I/O access patterns for the
46  * application to optimize resource utilization.
47  */
48 
49 /*!
50  * @typedef dispatch_fd_t
51  * Native file descriptor type for the platform.
52  */
53 #if defined(_WIN32)
54 typedef intptr_t dispatch_fd_t;
55 #else
56 typedef int dispatch_fd_t;
57 #endif
58 
59 /*!
60  * @functiongroup Dispatch I/O Convenience API
61  * Convenience wrappers around the dispatch I/O channel API, with simpler
62  * callback handler semantics and no explicit management of channel objects.
63  * File descriptors passed to the convenience API are treated as streams, and
64  * scheduling multiple operations on one file descriptor via the convenience API
65  * may incur more overhead than by using the dispatch I/O channel API directly.
66  */
67 
68 #ifdef __BLOCKS__
69 /*!
70  * @function dispatch_read
71  * Schedule a read operation for asynchronous execution on the specified file
72  * descriptor. The specified handler is enqueued with the data read from the
73  * file descriptor when the operation has completed or an error occurs.
74  *
75  * The data object passed to the handler will be automatically released by the
76  * system when the handler returns. It is the responsibility of the application
77  * to retain, concatenate or copy the data object if it is needed after the
78  * handler returns.
79  *
80  * The data object passed to the handler will only contain as much data as is
81  * currently available from the file descriptor (up to the specified length).
82  *
83  * If an unrecoverable error occurs on the file descriptor, the handler will be
84  * enqueued with the appropriate error code along with a data object of any data
85  * that could be read successfully.
86  *
87  * An invocation of the handler with an error code of zero and an empty data
88  * object indicates that EOF was reached.
89  *
90  * The system takes control of the file descriptor until the handler is
91  * enqueued, and during this time file descriptor flags such as O_NONBLOCK will
92  * be modified by the system on behalf of the application. It is an error for
93  * the application to modify a file descriptor directly while it is under the
94  * control of the system, but it may create additional dispatch I/O convenience
95  * operations or dispatch I/O channels associated with that file descriptor.
96  *
97  * @param fd		The file descriptor from which to read the data.
98  * @param length	The length of data to read from the file descriptor,
99  *			or SIZE_MAX to indicate that all of the data currently
100  *			available from the file descriptor should be read.
101  * @param queue		The dispatch queue to which the handler should be
102  *			submitted.
103  * @param handler	The handler to enqueue when data is ready to be
104  *			delivered.
105  *		param data	The data read from the file descriptor.
106  *		param error	An errno condition for the read operation or
107  *				zero if the read was successful.
108  */
109 API_AVAILABLE(macos(10.7), ios(5.0))
110 DISPATCH_EXPORT DISPATCH_NONNULL3 DISPATCH_NONNULL4 DISPATCH_NOTHROW
111 void
112 dispatch_read(dispatch_fd_t fd,
113 	size_t length,
114 	dispatch_queue_t queue,
115 	void (^handler)(dispatch_data_t data, int error));
116 
117 /*!
118  * @function dispatch_write
119  * Schedule a write operation for asynchronous execution on the specified file
120  * descriptor. The specified handler is enqueued when the operation has
121  * completed or an error occurs.
122  *
123  * If an unrecoverable error occurs on the file descriptor, the handler will be
124  * enqueued with the appropriate error code along with the data that could not
125  * be successfully written.
126  *
127  * An invocation of the handler with an error code of zero indicates that the
128  * data was fully written to the channel.
129  *
130  * The system takes control of the file descriptor until the handler is
131  * enqueued, and during this time file descriptor flags such as O_NONBLOCK will
132  * be modified by the system on behalf of the application. It is an error for
133  * the application to modify a file descriptor directly while it is under the
134  * control of the system, but it may create additional dispatch I/O convenience
135  * operations or dispatch I/O channels associated with that file descriptor.
136  *
137  * @param fd		The file descriptor to which to write the data.
138  * @param data		The data object to write to the file descriptor.
139  * @param queue		The dispatch queue to which the handler should be
140  *			submitted.
141  * @param handler	The handler to enqueue when the data has been written.
142  *		param data	The data that could not be written to the I/O
143  *				channel, or NULL.
144  *		param error	An errno condition for the write operation or
145  *				zero if the write was successful.
146  */
147 API_AVAILABLE(macos(10.7), ios(5.0))
148 DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NONNULL3 DISPATCH_NONNULL4
149 DISPATCH_NOTHROW
150 void
151 dispatch_write(dispatch_fd_t fd,
152 	dispatch_data_t data,
153 	dispatch_queue_t queue,
154 	void (^handler)(dispatch_data_t _Nullable data, int error));
155 #endif /* __BLOCKS__ */
156 
157 /*!
158  * @functiongroup Dispatch I/O Channel API
159  */
160 
161 /*!
162  * @typedef dispatch_io_t
163  * A dispatch I/O channel represents the asynchronous I/O policy applied to a
164  * file descriptor. I/O channels are first class dispatch objects and may be
165  * retained and released, suspended and resumed, etc.
166  */
167 DISPATCH_DECL(dispatch_io);
168 
169 /*!
170  * @typedef dispatch_io_type_t
171  * The type of a dispatch I/O channel:
172  *
173  * @const DISPATCH_IO_STREAM	A dispatch I/O channel representing a stream of
174  * bytes. Read and write operations on a channel of this type are performed
175  * serially (in order of creation) and read/write data at the file pointer
176  * position that is current at the time the operation starts executing.
177  * Operations of different type (read vs. write) may be performed simultaneously.
178  * Offsets passed to operations on a channel of this type are ignored.
179  *
180  * @const DISPATCH_IO_RANDOM	A dispatch I/O channel representing a random
181  * access file. Read and write operations on a channel of this type may be
182  * performed concurrently and read/write data at the specified offset. Offsets
183  * are interpreted relative to the file pointer position current at the time the
184  * I/O channel is created. Attempting to create a channel of this type for a
185  * file descriptor that is not seekable will result in an error.
186  */
187 #define DISPATCH_IO_STREAM 0
188 #define DISPATCH_IO_RANDOM 1
189 
190 typedef unsigned long dispatch_io_type_t;
191 
192 #ifdef __BLOCKS__
193 /*!
194  * @function dispatch_io_create
195  * Create a dispatch I/O channel associated with a file descriptor. The system
196  * takes control of the file descriptor until the channel is closed, an error
197  * occurs on the file descriptor or all references to the channel are released.
198  * At that time the specified cleanup handler will be enqueued and control over
199  * the file descriptor relinquished.
200  *
201  * While a file descriptor is under the control of a dispatch I/O channel, file
202  * descriptor flags such as O_NONBLOCK will be modified by the system on behalf
203  * of the application. It is an error for the application to modify a file
204  * descriptor directly while it is under the control of a dispatch I/O channel,
205  * but it may create additional channels associated with that file descriptor.
206  *
207  * @param type	The desired type of I/O channel (DISPATCH_IO_STREAM
208  *		or DISPATCH_IO_RANDOM).
209  * @param fd	The file descriptor to associate with the I/O channel.
210  * @param queue	The dispatch queue to which the handler should be submitted.
211  * @param cleanup_handler	The handler to enqueue when the system
212  *				relinquishes control over the file descriptor.
213  *	param error		An errno condition if control is relinquished
214  *				because channel creation failed, zero otherwise.
215  * @result	The newly created dispatch I/O channel or NULL if an error
216  *		occurred (invalid type specified).
217  */
218 API_AVAILABLE(macos(10.7), ios(5.0))
219 DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
220 DISPATCH_NOTHROW
221 dispatch_io_t
222 dispatch_io_create(dispatch_io_type_t type,
223 	dispatch_fd_t fd,
224 	dispatch_queue_t queue,
225 	void (^cleanup_handler)(int error));
226 
227 /*!
228  * @function dispatch_io_create_with_path
229  * Create a dispatch I/O channel associated with a path name. The specified
230  * path, oflag and mode parameters will be passed to open(2) when the first I/O
231  * operation on the channel is ready to execute and the resulting file
232  * descriptor will remain open and under the control of the system until the
233  * channel is closed, an error occurs on the file descriptor or all references
234  * to the channel are released. At that time the file descriptor will be closed
235  * and the specified cleanup handler will be enqueued.
236  *
237  * @param type	The desired type of I/O channel (DISPATCH_IO_STREAM
238  *		or DISPATCH_IO_RANDOM).
239  * @param path	The absolute path to associate with the I/O channel.
240  * @param oflag	The flags to pass to open(2) when opening the file at
241  *		path.
242  * @param mode	The mode to pass to open(2) when creating the file at
243  *		path (i.e. with flag O_CREAT), zero otherwise.
244  * @param queue	The dispatch queue to which the handler should be
245  *		submitted.
246  * @param cleanup_handler	The handler to enqueue when the system
247  *				has closed the file at path.
248  *	param error		An errno condition if control is relinquished
249  *				because channel creation or opening of the
250  *				specified file failed, zero otherwise.
251  * @result	The newly created dispatch I/O channel or NULL if an error
252  *		occurred (invalid type or non-absolute path specified).
253  */
254 API_AVAILABLE(macos(10.7), ios(5.0))
255 DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED
256 DISPATCH_WARN_RESULT DISPATCH_NOTHROW
257 dispatch_io_t
258 dispatch_io_create_with_path(dispatch_io_type_t type,
259 	const char *path, int oflag, mode_t mode,
260 	dispatch_queue_t queue,
261 	void (^cleanup_handler)(int error));
262 
263 /*!
264  * @function dispatch_io_create_with_io
265  * Create a new dispatch I/O channel from an existing dispatch I/O channel.
266  * The new channel inherits the file descriptor or path name associated with
267  * the existing channel, but not its channel type or policies.
268  *
269  * If the existing channel is associated with a file descriptor, control by the
270  * system over that file descriptor is extended until the new channel is also
271  * closed, an error occurs on the file descriptor, or all references to both
272  * channels are released. At that time the specified cleanup handler will be
273  * enqueued and control over the file descriptor relinquished.
274  *
275  * While a file descriptor is under the control of a dispatch I/O channel, file
276  * descriptor flags such as O_NONBLOCK will be modified by the system on behalf
277  * of the application. It is an error for the application to modify a file
278  * descriptor directly while it is under the control of a dispatch I/O channel,
279  * but it may create additional channels associated with that file descriptor.
280  *
281  * @param type	The desired type of I/O channel (DISPATCH_IO_STREAM
282  *		or DISPATCH_IO_RANDOM).
283  * @param io	The existing channel to create the new I/O channel from.
284  * @param queue	The dispatch queue to which the handler should be submitted.
285  * @param cleanup_handler	The handler to enqueue when the system
286  *				relinquishes control over the file descriptor
287  *				(resp. closes the file at path) associated with
288  *				the existing channel.
289  *	param error		An errno condition if control is relinquished
290  *				because channel creation failed, zero otherwise.
291  * @result	The newly created dispatch I/O channel or NULL if an error
292  *		occurred (invalid type specified).
293  */
294 API_AVAILABLE(macos(10.7), ios(5.0))
295 DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED
296 DISPATCH_WARN_RESULT DISPATCH_NOTHROW
297 dispatch_io_t
298 dispatch_io_create_with_io(dispatch_io_type_t type,
299 	dispatch_io_t io,
300 	dispatch_queue_t queue,
301 	void (^cleanup_handler)(int error));
302 
303 /*!
304  * @typedef dispatch_io_handler_t
305  * The prototype of I/O handler blocks for dispatch I/O operations.
306  *
307  * @param done		A flag indicating whether the operation is complete.
308  * @param data		The data object to be handled.
309  * @param error		An errno condition for the operation.
310  */
311 typedef void (^dispatch_io_handler_t)(bool done, dispatch_data_t _Nullable data,
312 		int error);
313 
314 /*!
315  * @function dispatch_io_read
316  * Schedule a read operation for asynchronous execution on the specified I/O
317  * channel. The I/O handler is enqueued one or more times depending on the
318  * general load of the system and the policy specified on the I/O channel.
319  *
320  * Any data read from the channel is described by the dispatch data object
321  * passed to the I/O handler. This object will be automatically released by the
322  * system when the I/O handler returns. It is the responsibility of the
323  * application to retain, concatenate or copy the data object if it is needed
324  * after the I/O handler returns.
325  *
326  * Dispatch I/O handlers are not reentrant. The system will ensure that no new
327  * I/O handler instance is invoked until the previously enqueued handler block
328  * has returned.
329  *
330  * An invocation of the I/O handler with the done flag set indicates that the
331  * read operation is complete and that the handler will not be enqueued again.
332  *
333  * If an unrecoverable error occurs on the I/O channel's underlying file
334  * descriptor, the I/O handler will be enqueued with the done flag set, the
335  * appropriate error code and a NULL data object.
336  *
337  * An invocation of the I/O handler with the done flag set, an error code of
338  * zero and an empty data object indicates that EOF was reached.
339  *
340  * @param channel	The dispatch I/O channel from which to read the data.
341  * @param offset	The offset relative to the channel position from which
342  *			to start reading (only for DISPATCH_IO_RANDOM).
343  * @param length	The length of data to read from the I/O channel, or
344  *			SIZE_MAX to indicate that data should be read until EOF
345  *			is reached.
346  * @param queue		The dispatch queue to which the I/O handler should be
347  *			submitted.
348  * @param io_handler	The I/O handler to enqueue when data is ready to be
349  *			delivered.
350  *	param done	A flag indicating whether the operation is complete.
351  *	param data	An object with the data most recently read from the
352  *			I/O channel as part of this read operation, or NULL.
353  *	param error	An errno condition for the read operation or zero if
354  *			the read was successful.
355  */
356 API_AVAILABLE(macos(10.7), ios(5.0))
357 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL4 DISPATCH_NONNULL5
358 DISPATCH_NOTHROW
359 void
360 dispatch_io_read(dispatch_io_t channel,
361 	off_t offset,
362 	size_t length,
363 	dispatch_queue_t queue,
364 	dispatch_io_handler_t io_handler);
365 
366 /*!
367  * @function dispatch_io_write
368  * Schedule a write operation for asynchronous execution on the specified I/O
369  * channel. The I/O handler is enqueued one or more times depending on the
370  * general load of the system and the policy specified on the I/O channel.
371  *
372  * Any data remaining to be written to the I/O channel is described by the
373  * dispatch data object passed to the I/O handler. This object will be
374  * automatically released by the system when the I/O handler returns. It is the
375  * responsibility of the application to retain, concatenate or copy the data
376  * object if it is needed after the I/O handler returns.
377  *
378  * Dispatch I/O handlers are not reentrant. The system will ensure that no new
379  * I/O handler instance is invoked until the previously enqueued handler block
380  * has returned.
381  *
382  * An invocation of the I/O handler with the done flag set indicates that the
383  * write operation is complete and that the handler will not be enqueued again.
384  *
385  * If an unrecoverable error occurs on the I/O channel's underlying file
386  * descriptor, the I/O handler will be enqueued with the done flag set, the
387  * appropriate error code and an object containing the data that could not be
388  * written.
389  *
390  * An invocation of the I/O handler with the done flag set and an error code of
391  * zero indicates that the data was fully written to the channel.
392  *
393  * @param channel	The dispatch I/O channel on which to write the data.
394  * @param offset	The offset relative to the channel position from which
395  *			to start writing (only for DISPATCH_IO_RANDOM).
396  * @param data		The data to write to the I/O channel. The data object
397  *			will be retained by the system until the write operation
398  *			is complete.
399  * @param queue		The dispatch queue to which the I/O handler should be
400  *			submitted.
401  * @param io_handler	The I/O handler to enqueue when data has been delivered.
402  *	param done	A flag indicating whether the operation is complete.
403  *	param data	An object of the data remaining to be
404  *			written to the I/O channel as part of this write
405  *			operation, or NULL.
406  *	param error	An errno condition for the write operation or zero
407  *			if the write was successful.
408  */
409 API_AVAILABLE(macos(10.7), ios(5.0))
410 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NONNULL4
411 DISPATCH_NONNULL5 DISPATCH_NOTHROW
412 void
413 dispatch_io_write(dispatch_io_t channel,
414 	off_t offset,
415 	dispatch_data_t data,
416 	dispatch_queue_t queue,
417 	dispatch_io_handler_t io_handler);
418 #endif /* __BLOCKS__ */
419 
420 /*!
421  * @typedef dispatch_io_close_flags_t
422  * The type of flags you can set on a dispatch_io_close() call
423  *
424  * @const DISPATCH_IO_STOP	Stop outstanding operations on a channel when
425  *				the channel is closed.
426  */
427 #define DISPATCH_IO_STOP 0x1
428 
429 typedef unsigned long dispatch_io_close_flags_t;
430 
431 /*!
432  * @function dispatch_io_close
433  * Close the specified I/O channel to new read or write operations; scheduling
434  * operations on a closed channel results in their handler returning an error.
435  *
436  * If the DISPATCH_IO_STOP flag is provided, the system will make a best effort
437  * to interrupt any outstanding read and write operations on the I/O channel,
438  * otherwise those operations will run to completion normally.
439  * Partial results of read and write operations may be returned even after a
440  * channel is closed with the DISPATCH_IO_STOP flag.
441  * The final invocation of an I/O handler of an interrupted operation will be
442  * passed an ECANCELED error code, as will the I/O handler of an operation
443  * scheduled on a closed channel.
444  *
445  * @param channel	The dispatch I/O channel to close.
446  * @param flags		The flags for the close operation.
447  */
448 API_AVAILABLE(macos(10.7), ios(5.0))
449 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
450 void
451 dispatch_io_close(dispatch_io_t channel, dispatch_io_close_flags_t flags);
452 
453 #ifdef __BLOCKS__
454 /*!
455  * @function dispatch_io_barrier
456  * Schedule a barrier operation on the specified I/O channel; all previously
457  * scheduled operations on the channel will complete before the provided
458  * barrier block is enqueued onto the global queue determined by the channel's
459  * target queue, and no subsequently scheduled operations will start until the
460  * barrier block has returned.
461  *
462  * If multiple channels are associated with the same file descriptor, a barrier
463  * operation scheduled on any of these channels will act as a barrier across all
464  * channels in question, i.e. all previously scheduled operations on any of the
465  * channels will complete before the barrier block is enqueued, and no
466  * operations subsequently scheduled on any of the channels will start until the
467  * barrier block has returned.
468  *
469  * While the barrier block is running, it may safely operate on the channel's
470  * underlying file descriptor with fsync(2), lseek(2) etc. (but not close(2)).
471  *
472  * @param channel	The dispatch I/O channel to schedule the barrier on.
473  * @param barrier	The barrier block.
474  */
475 API_AVAILABLE(macos(10.7), ios(5.0))
476 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
477 void
478 dispatch_io_barrier(dispatch_io_t channel, dispatch_block_t barrier);
479 #endif /* __BLOCKS__ */
480 
481 /*!
482  * @function dispatch_io_get_descriptor
483  * Returns the file descriptor underlying a dispatch I/O channel.
484  *
485  * Will return -1 for a channel closed with dispatch_io_close() and for a
486  * channel associated with a path name that has not yet been open(2)ed.
487  *
488  * If called from a barrier block scheduled on a channel associated with a path
489  * name that has not yet been open(2)ed, this will trigger the channel open(2)
490  * operation and return the resulting file descriptor.
491  *
492  * @param channel	The dispatch I/O channel to query.
493  * @result		The file descriptor underlying the channel, or -1.
494  */
495 API_AVAILABLE(macos(10.7), ios(5.0))
496 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_NOTHROW
497 dispatch_fd_t
498 dispatch_io_get_descriptor(dispatch_io_t channel);
499 
500 /*!
501  * @function dispatch_io_set_high_water
502  * Set a high water mark on the I/O channel for all operations.
503  *
504  * The system will make a best effort to enqueue I/O handlers with partial
505  * results as soon the number of bytes processed by an operation (i.e. read or
506  * written) reaches the high water mark.
507  *
508  * The size of data objects passed to I/O handlers for this channel will never
509  * exceed the specified high water mark.
510  *
511  * The default value for the high water mark is unlimited (i.e. SIZE_MAX).
512  *
513  * @param channel	The dispatch I/O channel on which to set the policy.
514  * @param high_water	The number of bytes to use as a high water mark.
515  */
516 API_AVAILABLE(macos(10.7), ios(5.0))
517 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
518 void
519 dispatch_io_set_high_water(dispatch_io_t channel, size_t high_water);
520 
521 /*!
522  * @function dispatch_io_set_low_water
523  * Set a low water mark on the I/O channel for all operations.
524  *
525  * The system will process (i.e. read or write) at least the low water mark
526  * number of bytes for an operation before enqueueing I/O handlers with partial
527  * results.
528  *
529  * The size of data objects passed to intermediate I/O handler invocations for
530  * this channel (i.e. excluding the final invocation) will never be smaller than
531  * the specified low water mark, except if the channel has an interval with the
532  * DISPATCH_IO_STRICT_INTERVAL flag set or if EOF or an error was encountered.
533  *
534  * I/O handlers should be prepared to receive amounts of data significantly
535  * larger than the low water mark in general. If an I/O handler requires
536  * intermediate results of fixed size, set both the low and and the high water
537  * mark to that size.
538  *
539  * The default value for the low water mark is unspecified, but must be assumed
540  * to be such that intermediate handler invocations may occur.
541  * If I/O handler invocations with partial results are not desired, set the
542  * low water mark to SIZE_MAX.
543  *
544  * @param channel	The dispatch I/O channel on which to set the policy.
545  * @param low_water	The number of bytes to use as a low water mark.
546  */
547 API_AVAILABLE(macos(10.7), ios(5.0))
548 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
549 void
550 dispatch_io_set_low_water(dispatch_io_t channel, size_t low_water);
551 
552 /*!
553  * @typedef dispatch_io_interval_flags_t
554  * Type of flags to set on dispatch_io_set_interval()
555  *
556  * @const DISPATCH_IO_STRICT_INTERVAL	Enqueue I/O handlers at a channel's
557  * interval setting even if the amount of data ready to be delivered is inferior
558  * to the low water mark (or zero).
559  */
560 #define DISPATCH_IO_STRICT_INTERVAL 0x1
561 
562 typedef unsigned long dispatch_io_interval_flags_t;
563 
564 /*!
565  * @function dispatch_io_set_interval
566  * Set a nanosecond interval at which I/O handlers are to be enqueued on the
567  * I/O channel for all operations.
568  *
569  * This allows an application to receive periodic feedback on the progress of
570  * read and write operations, e.g. for the purposes of displaying progress bars.
571  *
572  * If the amount of data ready to be delivered to an I/O handler at the interval
573  * is inferior to the channel low water mark, the handler will only be enqueued
574  * if the DISPATCH_IO_STRICT_INTERVAL flag is set.
575  *
576  * Note that the system may defer enqueueing interval I/O handlers by a small
577  * unspecified amount of leeway in order to align with other system activity for
578  * improved system performance or power consumption.
579  *
580  * @param channel	The dispatch I/O channel on which to set the policy.
581  * @param interval	The interval in nanoseconds at which delivery of the I/O
582  *					handler is desired.
583  * @param flags		Flags indicating desired data delivery behavior at
584  *					interval time.
585  */
586 API_AVAILABLE(macos(10.7), ios(5.0))
587 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
588 void
589 dispatch_io_set_interval(dispatch_io_t channel,
590 	uint64_t interval,
591 	dispatch_io_interval_flags_t flags);
592 
593 __END_DECLS
594 
595 DISPATCH_ASSUME_NONNULL_END
596 
597 #endif /* __DISPATCH_IO__ */