IHttpContext::IndicateCompletion Method
Indicates the completion of asynchronous work and requests that IIS resume execution on the calling thread.
Syntax
virtual VOID IndicateCompletion(
IN REQUEST_NOTIFICATION_STATUS notificationStatus
) = 0;
Parameters
notificationStatus
[IN] The notification status of the asyncronous operation.
Return Value
VOID
.
Remarks
An HTTP module can use the IndicateCompletion
method to indicate that an asynchronous operation has completed and request that IIS resume processing on the calling thread. This behavior is unlike the behavior of the PostCompletion method, which queues the execution to the thread pool.
If the status that is specified by the notificationStatus
parameter is not REQUEST_NOTIFICATION_PENDING, the request state computer will continue without reentering the original notification entry point.
Example
The following code example demonstrates how to create an HTTP module that uses the IndicateCompletion
method to indicate that an asynchronous operation has completed.
#define _WINSOCKAPI_
#include <windows.h>
#include <sal.h>
#include <httpserv.h>
// Create the module class.
class MyHttpModule : public CHttpModule
{
public:
REQUEST_NOTIFICATION_STATUS
OnBeginRequest(
IN IHttpContext * pHttpContext,
IN IHttpEventProvider * pProvider
)
{
UNREFERENCED_PARAMETER( pProvider );
// Create an HRESULT to receive return values from methods.
HRESULT hr;
// Create a string to return to a Web client.
PCSTR pszBuffer = "Hello World!";
// Clear the existing response.
pHttpContext->GetResponse()->Clear();
// Set the MIME type to plain text.
pHttpContext->GetResponse()->SetHeader(
HttpHeaderContentType,"text/plain",
(USHORT)strlen("text/plain"),TRUE);
// Create a data chunk. (Defined in the Http.h file.)
HTTP_DATA_CHUNK dataChunk;
// Set the chunk to a chunk in memory.
dataChunk.DataChunkType = HttpDataChunkFromMemory;
// Buffer for bytes written of data chunk.
DWORD cbSent;
// Set the completion expected flag to false.
BOOL pfCompletionExpected = FALSE;
// Set the chunk to the buffer.
dataChunk.FromMemory.pBuffer = (PVOID) pszBuffer;
// Set the chunk size to the buffer size.
dataChunk.FromMemory.BufferLength = (USHORT) strlen(pszBuffer);
// Insert the data chunk into the response.
hr = pHttpContext->GetResponse()->WriteEntityChunks(
&dataChunk,1,TRUE,TRUE,&cbSent,&pfCompletionExpected);
// Test for an error.
if (FAILED(hr))
{
// Return the error status and exit.
pProvider->SetErrorStatus(hr);
return RQ_NOTIFICATION_FINISH_REQUEST;
}
if (TRUE == pfCompletionExpected)
{
// Notify IIS that an asynchronous completion is expected.
return RQ_NOTIFICATION_PENDING;
}
// Flush the response to the client.
hr = pHttpContext->GetResponse()->Flush(TRUE,FALSE,&cbSent,&pfCompletionExpected);
// Test for an error.
if (FAILED(hr))
{
// Return the error status and exit.
pProvider->SetErrorStatus(hr);
return RQ_NOTIFICATION_FINISH_REQUEST;
}
if (TRUE == pfCompletionExpected)
{
// Notify IIS that an asynchronous completion is expected.
return RQ_NOTIFICATION_PENDING;
}
// End additional processing.
return RQ_NOTIFICATION_FINISH_REQUEST;
}
REQUEST_NOTIFICATION_STATUS OnAsyncCompletion(
IN IHttpContext* pHttpContext,
IN DWORD dwNotification,
IN BOOL fPostNotification,
IN OUT IHttpEventProvider* pProvider,
IN IHttpCompletionInfo* pCompletionInfo
)
{
// Indicate completion for the operation.
pHttpContext->IndicateCompletion(RQ_NOTIFICATION_CONTINUE);
// Return processing to the pipeline.
return RQ_NOTIFICATION_PENDING;
}
};
// Create the module's class factory.
class MyHttpModuleFactory : public IHttpModuleFactory
{
public:
HRESULT
GetHttpModule(
OUT CHttpModule ** ppModule,
IN IModuleAllocator * pAllocator
)
{
UNREFERENCED_PARAMETER( pAllocator );
// Create a new instance.
MyHttpModule * pModule = new MyHttpModule;
// Test for an error.
if (!pModule)
{
// Return an error if we cannot create the instance.
return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
}
else
{
// Return a pointer to the module.
*ppModule = pModule;
pModule = NULL;
// Return a success status.
return S_OK;
}
}
void Terminate()
{
// Remove the class from memory.
delete this;
}
};
// Create the module's exported registration function.
HRESULT
__stdcall
RegisterModule(
DWORD dwServerVersion,
IHttpModuleRegistrationInfo * pModuleInfo,
IHttpServer * pGlobalInfo
)
{
UNREFERENCED_PARAMETER( dwServerVersion );
UNREFERENCED_PARAMETER( pGlobalInfo );
// Set the request notifications and exit.
return pModuleInfo->SetRequestNotifications(
new MyHttpModuleFactory,
RQ_BEGIN_REQUEST,
0
);
}
Your module must export the RegisterModule function. You can export this function by creating a module definition (.def) file for your project, or you can compile the module by using the /EXPORT:RegisterModule
switch. For more information, see Walkthrough: Creating a Request-Level HTTP Module By Using Native Code.
You can optionally compile the code by using the __stdcall (/Gz)
calling convention instead of explicitly declaring the calling convention for each function.
Requirements
Type | Description |
---|---|
Client | - IIS 7.0 on Windows Vista - IIS 7.5 on Windows 7 - IIS 8.0 on Windows 8 - IIS 10.0 on Windows 10 |
Server | - IIS 7.0 on Windows Server 2008 - IIS 7.5 on Windows Server 2008 R2 - IIS 8.0 on Windows Server 2012 - IIS 8.5 on Windows Server 2012 R2 - IIS 10.0 on Windows Server 2016 Technical Preview |
Product | - IIS 7.0, IIS 7.5, IIS 8.0, IIS 8.5, IIS 10.0 - IIS Express 7.5, IIS Express 8.0, IIS Express 10.0 |
Header | Httpserv.h |