Overlapped I/OThe first requirement for asynchronous I/O, whether overlapped or extended, is to set the overlapped attribute of the file or other handle. This is done by specifying the FILE_FLAG_OVERLAPPED flag on the CreateFile or other call that creates the file, named pipe, or other handle. Sockets (Chapter 12), whether created by socket or accept, have the overlapped attribute set by default in Winsock 1.1, but the attribute must be set explicitly in Winsock 2.0. An overlapped socket can be used asynchronously in all Windows versions. Until now, overlapped structures have been used with LockFileEx and as an alternative to SetFilePointer (Chapter 3), but they are essential for overlapped I/O. These structures are optional parameters on four I/O functions that can potentially block while the operation completes:
Recall that when you're specifying FILE_FLAG_OVERLAPPED as part of dwAttrsAndFlags (for CreateFile) or as part of dwOpenMode (for CreateNamedPipe), the pipe or file is to be used only in overlapped mode. Overlapped I/O does not work with anonymous pipes. Note: The CreateFile documentation suggests that using the FILE_FLAG_NO_BUFFERING flag will enhance overlapped I/O performance. Experiments show a small improvement (about 15 percent, as can be verified by experimenting with Program 14-1), but you must ensure that the read length of every ReadFile and WriteFile operation is a multiple of the disk sector size. Overlapped SocketsOne of the most important additions to Windows Sockets 2.0 (Chapter 12) is the standardization of overlapped I/O. In particular, sockets are no longer created automatically as overlapped file handles. socket creates a nonoverlapped handle. To create an overlapped socket, call WSASocket and explicitly ask for one by setting the dwFlags parameter of WSASocket to WSA_FLAG_OVERLAPPED.
Use WSASocket, rather than socket, to create the socket. Any socket returned by accept will have the same properties as the argument. Consequences of Overlapped I/OOverlapped I/O is asynchronous. There are several consequences.
The last two issues listed abovefile position and synchronizationare addressed by the overlapped structures. Overlapped StructuresThe OVERLAPPED structure (specified, for example, by the lpOverlapped parameter of ReadFile) indicates the following:
Here is the OVERLAPPED structure.
The file position (pointer) must be set in both Offset and OffsetHigh, although the high-order portion is frequently 0. Do not use Internal and InternalHigh, which are reserved for the system. hEvent is an event handle (created with CreateEvent). The event can be named or unnamed, but it should be a manual-reset event (see Chapter 8) when used for overlapped I/O; the reasons are explained soon. The event is signaled when the I/O operation completes. Alternatively, hEvent can be NULL; in this case, the program can wait on the file handle, which is also a synchronization object (see the upcoming list of cautions). The system signals completion on the file handle when hEvent is NULL, that is, the file handle becomes the synchronization object. Note: For convenience. the term "file handle" is used to describe the handle with ReadFile, WriteFile, and so on, even though this handle could refer to a pipe or device rather than to a file. This event is immediately reset (set to the nonsignaled state) by the system when the program makes an I/O call. When the I/O operation completes, the event is signaled and remains signaled until it is used with another I/O operation. The event needs to be manual-reset if multiple threads might wait on it (although our example uses only one thread), and they may not be waiting at the time the operation completes. Even if the file handle is synchronous (it was created without FILE_FLAG_OVERLAPPED), the overlapped structure is an alternative to SetFilePointer for specifying file position. In this case, the ReadFile or other call does not return until the operation is complete. This feature was used in Chapter 3. Notice also that an outstanding I/O operation is uniquely identified by the combination of file handle and overlapped structure. Here are a few cautions to keep in mind.
Overlapped I/O StatesAn overlapped ReadFile or WriteFile operationor, for that matter, one of the two named pipe operationsreturns immediately. In most cases, the I/O will not be complete, and the read or write returns FALSE. GetLastError returns ERROR_IO_PENDING. After waiting on a synchronization object (an event or, perhaps, the file handle) for the operation to complete, you need to determine how many bytes were transferred. This is the primary purpose of GetOverlappedResult.
The handle and overlapped structure combine to indicate the specific I/O operation. bWait, if trUE, specifies that GetOverlappedResult will wait until the specified operation is complete; otherwise, it returns immediately. In either case, the function returns trUE only if the operation has completed successfully. GetLastError returns ERROR_IO_INCOMPLETE in case of a FALSE return from GetOverlappedResult, so it is possible to poll for I/O completion with this function. The number of bytes transferred is in *lpcbTransfer. Be certain that the overlapped structure is unchanged from when it was used with the overlapped I/O operation. Canceling Overlapped I/O OperationsThe Boolean function CancelIO cancels outstanding overlapped I/O operations on the specified handle (there is just one parameter). All operations issued by the calling thread using the handle are canceled. Operations initiated by other threads are not affected. The canceled operations will complete with ERROR_OPERATION_ABORTED. |
Thursday, November 12, 2009
Overlapped I/O
Subscribe to:
Post Comments (Atom)
Explained in an elaborate fashion, and answered some of the questions I had about why do we issue a IO call with the event set to signaled state, as seen in the example on msdn website. After reading this blog I realized that its because the system will reset the event right away. However, there is some information that seemed to be missing in this blog post about the ERROR_PIPE_CONNECTED after a called to something like ConnectNamedPipe. In this case is the event already set if the client has attempted to do an IO to the pipe ?
ReplyDelete