ptg10805159
520 Advanced I/O Chapter 14
numop--;
break;
}
}
if (numop == 0) {
if (off >= sbuf.st_size)
break;
}else {
if (aio_suspend(aiolist, NBUF, NULL) < 0)
err_sys("aio_suspend failed");
}
}
bufs[0].aiocb.aio_fildes = ofd;
if (aio_fsync(O_SYNC, &bufs[0].aiocb) < 0)
err_sys("aio_fsync failed");
exit(0);
}
Figure 14.21 Tr anslate a file using ROT-13 and asynchronous I/O
Note that we use eight buffers, so we can have up to eight asynchronous I/O
requests pending. Surprisingly,this might actually reduce performance—ifthe reads
arepresented to the file system out of order, it can defeat the operating system’s read-
ahead algorithm.
Before we can check the return value of an operation, we need to make surethe
operation has completed. Whenaio_errorreturns a value other thanEINPROGRESS
or−1, we know the operation is complete. Excluding these values, if the return value is
anything other than 0, then we know the operation failed. Once we’ve checked these
conditions, it is safe to callaio_returnto get the return value of the I/O operation.
As long as we have work to do, we can submit asynchronous I/O operations.
When we have an unused AIO control block, we can submit an asynchronous read
request. Whenaread completes, we translate the buffer contents and then submit an
asynchronous write request. When all AIO control blocks are in use, we wait for an
operation to complete by callingaio_suspend.
When we write a block to the output file, we retain the same offset at which we read
the data from the input file. Consequently,the order of the writes doesn’t matter.This
strategy works only because each character in the input file has a corresponding
character in the output file at the same offset; we neither add nor delete characters in the
output file. (This insight might help solve Exercise 14.8.)
We don’t use asynchronous notification in this example, because it is easier to use a
synchronous programming model. If we had something else to do while the I/O
operations were in progress, then the additional work could be folded into thefor
loop. If we needed to prevent this additional work from delaying the task of translating
the file, however,then we might have to structurethe code to use some form of
asynchronous notification. With multiple tasks, we need to prioritize the tasks before
deciding how the program should be structured.