qio_util - Queued Input/Output Utilities

The 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->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.

Public Procedures

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.

Macro Definitions

qioWait() - waits for all outstanding I/O requests in a queue to complete.

Source Files


Alex Measday  /  E-mail