|
|
|
qio_util
- Queued Input/Output UtilitiesThe QIO_UTIL functions implement a VMS-style queued I/O request package. (See Non-Blocking I/O, One Way or Another for the description of an earlier QIO package.) Read, write, and seek operations can be queued up on a device channel (e.g., a network socket). Periodic calls to a flush function will attempt to complete any pending operations. If the device channels managed by the QIO package are configured for non-blocking I/O, the user program can perform other tasks without having to wait for all its I/O requests to complete.
A separate I/O queue must be created and associated with each I/O device that will make use of queued I/O:
#include "qio_util.h" -- Queued I/O utilities. IoQueue queue ; int fd = opened device's file descriptor ; ... qioCreate (fd, NULL, &queue) ;
Once the I/O queue is created, read, seek, and write operations can be queued up on the channel:
void buffer[1024] ; ... ... fill the buffer with useful data ... ... qioWrite (queue, buffer, sizeof buffer, QioStatic, NULL, NULL) ;
To process queued I/O requests, qioFlush()
must be periodically
called in order to complete any outstanding requests:
qioFlush (queue) ;
Rather than making timed calls to qioFlush()
, a more sophisticated
application could use the file descriptor returned by qioFd()
to
construct an I/O mask for the select(2)
system call.
When an I/O operation completes, the request is removed from its queue. The originator of the request has the option of specifying a completion function to be called when the request completes. (In line with the VMS inspiration for this package, the completion function is called an asynchronous trap, or AST, function.) The completion function is passed an I/O status block that contains the completion status for the I/O operation:
#include <stdio.h> -- Standard I/O definitions. ... void onCompletion (IoQueue queue, IoRequest request, QioStatus *iosb, void *argument) { printf ("%ld bytes %s written to channel %d (%s).\n", iosb->transferred, iosb->status ? "unsuccessfully" : "successfully", qioFd (queue), (char *) argument) ; } ... qioWrite (queue, buffer, sizeof buffer, QioStatic, onCompletion, "/dev/rmt0") ;
Outstanding I/O requests can be cancelled individually:
IoRequest request = qioSeek (queue, 123, NULL, NULL) ; ... qioCancel (queue, request) ;
or en masse:
qioDestroy (queue) ;
This last call only destroys the queue; it does NOT close the channel.
qioCancel()
- cancels an outstanding I/O request.
qioCreate()
- creates an I/O queue.
qioDestroy()
- destroys an I/O queue.
qioFd()
- returns an I/O queue's file descriptor.
qioFlush()
- attempts to complete any outstanding I/O requests in a queue.
qioFlushNext()
- attempts to complete the next outstanding I/O request in a queue.
qioPending()
- returns the number of outstanding I/O requests in a queue.
qioRead()
- adds a read request to an I/O queue.
qioSeek()
- adds a seek request to an I/O queue.
qioWrite()
- adds a write request to an I/O queue.
qioWait()
- waits for all outstanding I/O requests in a queue to complete.
qio_util.c
qio_util.h