Asynchronous I/O operations are frequently the most efficient choices when developing ISAPI extensions. For an overview of asynchronous operations in ISAPI, see Asynchronous I/O Processing.
In order to perform asynchronous reads, your ISAPI extension must perform the following steps:
Note that only one asynchronous read operation can be pending for each ISAPI extension at any given time. If your ISAPI extension has issued a request for an asynchronous read, and you have determined that the request has timed out, you can cancel the request and close the connection by using the HSE_REQ_CLOSE_CONNECTION ServerSupportFunction. If you do this, however, you must still wait for IIS to call the asynchronous callback function before you can consider the connection terminated.
There are two options available to ISAPI extensions for performing asynchronous write operations. One option uses an asynchronous flavor of the WriteClient function, the other uses the functionality provided by the Win32 API TransmitFile function through the HSE_REQ_TRANSMIT_FILE ServerSupportFunction.
Tip In most cases, using the TransmitFile-based ServerSupportFunction will yield the highest performance.
Both options are included in the following procedure:
The following code initiates an asynchronous read from a client.
DWORD DoAsyncRC(
EXTENSION_CONTROL_BLOCK * pecb
)
{
char szHeader[256] = "";
BOOL fReturn = TRUE;
DWORD dwFlags;
DWORD cbTotalToRead = MAX_BUF_SIZE;
DWORD hseStatus = HSE_STATUS_PENDING;
// Initialize the context for ReadClient.
pByteReadSoFar = &(pecb->cbAvailable);
// Specify the asynchronous callback function.
fReturn = pecb->ServerSupportFunction(
pecb->ConnID,
HSE_REQ_IO_COMPLETION,
AsyncReadClientIoCompletion,
0,
pByteReadSoFar
);
// Error?
if (!fReturn) {
hseStatus = HSE_STATUS_ERROR;
}
// Request that IIS begin asynchronous read operation.
dwFlags = HSE_IO_ASYNC;
fReturn = pecb->ServerSupportFunction(
pecb->ConnID,
HSE_REQ_ASYNC_READ_CLIENT,
g_ReadBuffer,
&cbTotalToRead,
&dwFlags
);
// Error?
if (!fReturn) {
hseStatus = HSE_STATUS_ERROR;
}
// Return HSE_STATUS_PENDING, unless an error occurred.
return (hseStatus);
}
For complete working samples that demonstrate all the possible synchronous and asynchronous operations, see the Synchronous and Asynchronous I/O sample.