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