|
|
//+-----------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (c) Microsoft Corporation
//
// File: kpcore.cxx
//
// Contents: core routine for worker threads
//
// History: 10-Jul-2001 t-ryanj Created
//
//------------------------------------------------------------------------
#include "kpcore.h"
#include "kphttp.h"
#include "kpkdc.h"
VOID KpDispatchPerContext( PKPCONTEXT pContext, ULONG IocpBytes );
//+-------------------------------------------------------------------------
//
// Function: KpThreadCore
//
// Synopsis: core routine for worker threads. handles requests as they
// are posted to the completion port.
//
// Effects:
//
// Arguments: ignore - unused
//
// Requires:
//
// Returns: always 0
//
// Notes:
//
//
//--------------------------------------------------------------------------
DWORD WINAPI KpThreadCore( LPVOID pvContext ) { KpDispatchPerContext((PKPCONTEXT)pvContext, 0 );
return NO_ERROR; #if 0
BOOL Terminate = FALSE; BOOL IocpSuccess; ULONG IocpBytes; ULONG_PTR IocpCompKey; LPOVERLAPPED lpOverlapped;
//
// Do it til we're done.
//
while( !Terminate ) { //
// Grab a job off the completion queue.
//
IocpSuccess = GetQueuedCompletionStatus( KpGlobalIocp, &IocpBytes, &IocpCompKey, &lpOverlapped, INFINITE ); if( !IocpSuccess ) { DebugLog( DEB_ERROR, "%s(%d): Error from GetQueuedCompletionStatus: 0x%x.\n", __FILE__, __LINE__, GetLastError() ); continue; }
//
// Based on the completion key, do the right thing.
//
switch( IocpCompKey ) { case KPCK_TERMINATE: Terminate = TRUE; break;
case KPCK_HTTP_INITIAL: DebugLog( DEB_TRACE, "----==== New connection accepted ====----\n" ); KpHttpRead( (LPEXTENSION_CONTROL_BLOCK)lpOverlapped ); break;
case KPCK_CHECK_CONTEXT: KpDispatchPerContext( KpGetContextFromOl( lpOverlapped ), IocpBytes ); break;
default: DebugLog( DEB_WARN, "%s(%d): Unhandled case: 0x%x.\n", __FILE__, __LINE__, IocpCompKey ); DsysAssert( IocpCompKey == KPCK_TERMINATE || IocpCompKey == KPCK_HTTP_INITIAL || IocpCompKey == KPCK_CHECK_CONTEXT ); break; } }
return 0; #endif
}
VOID CALLBACK KpIoCompletionRoutine( DWORD dwErrorCode, DWORD dwBytes, LPOVERLAPPED lpOverlapped ) { PKPCONTEXT pContext = NULL;
if( lpOverlapped ) { pContext = KpGetContextFromOl( lpOverlapped ); } else { DebugLog( DEB_ERROR, "%s(%d): Null pointer for overlapped.\n", __FILE__, __LINE__ ); goto Error; }
if( dwErrorCode ) { DebugLog( DEB_ERROR, "%s(%d): Error from I/O routine: 0x%x\n", __FILE__, __LINE__, dwErrorCode ); goto Error; }
KpDispatchPerContext( pContext, dwBytes );
return;
Error: if( pContext ) KpReleaseContext( pContext ); }
//+-------------------------------------------------------------------------
//
// Function: KpDispatchPerContext
//
// Synopsis: Does the right things based on the status in the context.
//
// Effects:
//
// Arguments: pContext
// IocpBytes - bytes reported to the iocp
//
// Requires:
//
// Returns:
//
// Notes:
//
//
//--------------------------------------------------------------------------
VOID KpDispatchPerContext( PKPCONTEXT pContext, ULONG IocpBytes ) { //
// Status is going to tell us what we just finished doing,
// so we can pass the context into the next step.
//
switch( pContext->dwStatus ) { case KP_HTTP_INITIAL: KpHttpRead(pContext); break;
case KP_HTTP_READ: KpKdcWrite(pContext); break;
case KP_KDC_WRITE: DebugLog( DEB_TRACE, "%s(%d): %d bytes written to KDC.\n", __FILE__, __LINE__, pContext->ol.InternalHigh ); KpKdcRead(pContext); break;
case KP_KDC_READ: DebugLog( DEB_PEDANTIC, "%s(%d): %d bytes read from KDC.\n", __FILE__, __LINE__, pContext->ol.InternalHigh );
//
// If we don't know how many bytes we're looking for yet,
// figure it out.
//
if( pContext->bytesExpected == 0 && !KpCalcLength(pContext) ) { goto Error; }
//
// If we're done reading, start writing; otherwise, read some more.
//
if( KpKdcReadDone(pContext) ) { DebugLog( DEB_TRACE, "%s(%d): %d total bytes read from KDC.\n", __FILE__, __LINE__, pContext->bytesReceived ); KpHttpWrite(pContext); } else { KpKdcRead(pContext); } break; case KP_HTTP_WRITE: DebugLog( DEB_TRACE, "%s(%d): %d bytes written to http.\n", __FILE__, __LINE__, pContext->bytesReceived ); KpReleaseContext( pContext ); break;
default: DebugLog( DEB_WARN, "%s(%d): Unhandled case: 0x%x.\n", __FILE__, __LINE__, pContext->dwStatus ); DsysAssert( pContext->dwStatus == KP_HTTP_READ || pContext->dwStatus == KP_KDC_WRITE || pContext->dwStatus == KP_KDC_READ || pContext->dwStatus == KP_HTTP_WRITE ); goto Error; break; }
return;
Error: //
// This is where we get when we're not sure what to do with the connection next, so
// we'll just close the connection.
//
KpReleaseContext( pContext ); }
|