dispatch_io_create(3) | Library Functions Manual | dispatch_io_create(3) |
dispatch_io_create
,
dispatch_io_create_with_path
,
dispatch_io_close
,
dispatch_io_set_high_water
,
dispatch_io_set_low_water
,
dispatch_io_set_interval
,
dispatch_io_barrier
— open,
close and configure dispatch I/O channels
#include
<dispatch/dispatch.h>
dispatch_io_t
dispatch_io_create
(dispatch_io_type_t
type, int fd, dispatch_queue_t
queue, void (^cleanup_handler)(int error));
dispatch_io_t
dispatch_io_create_with_path
(dispatch_io_type_t
type, const char *path, int
oflag, mode_t mode,
dispatch_queue_t queue, void
(^cleanup_handler)(int error));
void
dispatch_io_close
(dispatch_io_t
channel, dispatch_io_close_flags_t flags);
void
dispatch_io_set_high_water
(dispatch_io_t
channel, size_t high_water);
void
dispatch_io_set_low_water
(dispatch_io_t
channel, size_t low_water);
void
dispatch_io_set_interval
(dispatch_io_t
channel, uint64_t interval,
dispatch_io_interval_flags_t flags);
void
dispatch_io_barrier
(dispatch_io_t
channel, void (^barrier)(void));
The dispatch I/O framework is an API for asynchronous read and write I/O operations. It is an application of the ideas and idioms present in the dispatch(3) framework to device I/O. Dispatch I/O enables an application to more easily avoid blocking I/O operations and allows it to more directly express its I/O requirements than by using the raw POSIX file API. Dispatch I/O will make a best effort to optimize how and when asynchronous I/O operations are performed based on the capabilities of the targeted device.
This page provides details on how to create and configure dispatch I/O channels. Reading from and writing to these channels is covered in the dispatch_io_read(3) page. The dispatch I/O framework also provides the convenience functions dispatch_read(3) and dispatch_write(3) for uses that do not require the full functionality provided by I/O channels.
A dispatch I/O channel represents the asynchronous I/O policy applied to a file descriptor and encapsulates it for the purposes of ownership tracking while I/O operations are ongoing.
Dispatch I/O channels can have one of the following types:
The
dispatch_io_create
()
and
dispatch_io_create_with_path
()
functions create a dispatch I/O channel of provided
type from a file descriptor fd
or an absolute pathname, respectively. They can be thought of as analogous
to the fdopen(3) POSIX function and the
fopen(3) function in the standard C
library. For a channel created from a pathname, the provided
path, oflag and
mode parameters will be passed to
open(2) when the first I/O operation on
the channel is ready to execute.
The provided cleanup_handler block will be submitted to the specified queue when all I/O operations on the channel have completed and it is closed or reaches the end of its lifecycle. If an error occurs during channel creation, the cleanup_handler block will be submitted immediately and passed an error parameter with the POSIX error encountered. If an invalid type or a non-absolute path argument is specified, these functions will return NULL and the cleanup_handler will not be invoked. After successfully creating a dispatch I/O channel from a file descriptor, the application must take care not to modify that file descriptor until the associated cleanup_handler is invoked, see FILEDESCRIPTOR OWNERSHIP for details.
The
dispatch_io_close
()
function closes a dispatch I/O channel to new submissions of I/O operations.
If DISPATCH_IO_STOP
is passed in the
flags parameter, the system will in addition not
perform the I/O operations already submitted to the channel that are still
pending and will make a best effort to interrupt any ongoing operations.
Handlers for operations so affected will be passed the
ECANCELED
error code, along with any partial
results.
Dispatch I/O channels have high-water mark, low-water mark and interval configuration settings that determine if and when partial results from I/O operations are delivered via their associated I/O handlers.
The
dispatch_io_set_high_water
()
and
dispatch_io_set_low_water
()
functions configure the water mark settings of a
channel. The system will read or write at least the
number of bytes specified by low_water before
submitting an I/O handler with partial results, and will make a best effort
to submit an I/O handler as soon as the number of bytes read or written
reaches high_water.
The
dispatch_io_set_interval
()
function configures the time interval at which I/O
handlers are submitted (measured in nanoseconds). If
DISPATCH_IO_STRICT_INTERVAL
is passed in the
flags parameter, the interval will be strictly
observed even if there is an insufficient amount of data to deliver;
otherwise delivery will be skipped for intervals where the amount of
available data is inferior to the channel's low-water mark. Note that the
system may defer enqueueing interval I/O handlers by a small unspecified
amount of leeway in order to align with other system activity for improved
system performance or power consumption.
The size of data objects passed to I/O handlers for a channel will never be larger than the high-water mark set on the channel; it will also never be smaller than the low-water mark, except in the following cases:
DISPATCH_IO_STRICT_INTERVAL
flag setSIZE_MAX
). Channels that require intermediate
results of fixed size should have both the low-water and the high-water mark
set to that size. Channels that do not wish to receive any intermediate
results should have the low-water mark set to
SIZE_MAX
.
When an application creates a dispatch I/O channel from a file
descriptor with the dispatch_io_create
() function,
the system takes control of that file descriptor until the channel is
closed, an error occurs on the file descriptor or all references to the
channel are released. At that time the channel's cleanup handler will be
enqueued and control over the file descriptor relinquished, making it safe
for the application to close(2) the file
descriptor. While a file descriptor is under the control of a dispatch I/O
channel, file descriptor flags such as O_NONBLOCK
will be modified by the system on behalf of the application. It is an error
for the application to modify a file descriptor directly while it is under
the control of a dispatch I/O channel, but it may create further I/O
channels from that file descriptor or use the
dispatch_read(3) and
dispatch_write(3) convenience
functions with that file descriptor. If multiple I/O channels have been
created from the same file descriptor, all the associated cleanup handlers
will be submitted together once the last channel has been closed resp. all
references to those channels have been released. If convenience functions
have also been used on that file descriptor, submission of their handlers
will be tied to the submission of the channel cleanup handlers as well.
The
dispatch_io_barrier
()
function schedules a barrier operation on an I/O channel. The specified
barrier block will be run once, after all current I/O operations (such as
read(2) or
write(2)) on the underlying file
descriptor have finished. No new I/O operations will start until the barrier
block finishes.
The barrier block may operate on the underlying file descriptor with functions like fsync(2) or lseek(2). As discussed in the FILEDESCRIPTOR OWNERSHIP section, the barrier block must not close(2) the file descriptor, and if it changes any flags on the file descriptor, it must restore them before finishing.
There is no synchronization between a barrier block and any dispatch_io_read(3) or dispatch_io_write(3) handler blocks; they may be running at the same time. The barrier block itself is responsible for any required synchronization.
Dispatch I/O channel objects are retained and released via calls
to
dispatch_retain
()
and
dispatch_release
().
open(2), dispatch(3), dispatch_io_read(3), dispatch_object(3), dispatch_read(3), fopen(3)
December 1, 2010 | Darwin |