home *** CD-ROM | disk | FTP | other *** search
- // KeepAliveP.c -> Sample ISAPI Extension demonstrating Keep-Alive with a thread pool
-
- #define _WIN32_WINNT 0x0400
-
- #include <windows.h>
- #include <httpext.h>
- #include <stdio.h>
- #include "threadpool.h"
-
-
- BOOL WINAPI DllMain(IN HINSTANCE hinstDll, IN DWORD fdwReason, IN LPVOID lpvContext OPTIONAL)
- {
- BOOL fReturn=TRUE;
-
- switch (fdwReason )
- {
- case DLL_PROCESS_ATTACH:
- fReturn=InitThreadPool();
- break;
- }
-
- return fReturn;
- }
-
-
- BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO *pVer)
- {
- pVer->dwExtensionVersion = MAKELONG(HSE_VERSION_MINOR, HSE_VERSION_MAJOR);
- lstrcpyn(pVer->lpszExtensionDesc, "ISAPI Keep-Alive with Thread Pool Extension Sample",
- HSE_MAX_EXT_DLL_NAME_LEN);
-
- return TRUE;
- }
-
-
- DWORD WINAPI HttpExtensionProc(EXTENSION_CONTROL_BLOCK *pECB)
- {
- DWORD dwSize;
- char szHeader[]="Connection: Keep-Alive\r\nContent-Length: %lu\r\nContent-type: text/html\r\n\r\n";
- char szBusyMessage[]="<html> <form method=get action=KeepAliveP.dll> <input type=submit> "
- "<br>pECB->ConnID=%lu <br>Server was too busy. </form></html>";
- char szBuffer[4096];
- char szBuffer2[4096];
-
- EnterCriticalSection(&csQueueLock);
- if(!AddWorkQueueEntry(pECB)) // if ECB could not be assigned
- {
- LeaveCriticalSection(&csQueueLock);
-
- sprintf(szBuffer2, szBusyMessage, pECB->ConnID);
-
- // Send outgoing header
- sprintf(szBuffer, szHeader, strlen(szBuffer2));
- dwSize = strlen(szBuffer);
- pECB->ServerSupportFunction(pECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER,
- NULL, &dwSize, (unsigned long *)szBuffer);
-
- // Send content
- dwSize = strlen(szBuffer2);
- pECB->WriteClient(pECB->ConnID, szBuffer2, &dwSize, 0);
-
- return HSE_STATUS_SUCCESS_AND_KEEP_CONN;
- }
- else
- {
- ReleaseSemaphore( hWorkSem, 1, NULL ); //Release 1 thread from pool
- LeaveCriticalSection(&csQueueLock);
- }
-
- return HSE_STATUS_PENDING;
- }
-
-
- DWORD WINAPI WorkerFunction(LPVOID pvThreadNum)
- {
- EXTENSION_CONTROL_BLOCK *pECB;
- DWORD dwRet, dwState, dwSize, dwThreadNum;
-
- //This header will be filled in with the content length
- char szHeader[]="Connection: Keep-Alive\r\nContent-Length: %lu\r\nContent-type: text/html\r\n\r\n";
- char szContent[]="<html> <form method=get action=KeepAliveP.dll><input type=submit> "\
- "<br>pECB->ConnID=%lu <br>dwThreadNum=%lu</form></html>";
- char szBuffer[4096];
- char szBuffer2[4096];
-
- dwThreadNum=(DWORD)pvThreadNum;
-
- while(TRUE)
- {
- dwRet = WaitForSingleObject( hWorkSem, INFINITE );
- if ( dwRet == WAIT_OBJECT_0 )
- {
-
- EnterCriticalSection(&csQueueLock);
-
- if( GetWorkQueueEntry(&pECB) ) // Found work to do
- {
- LeaveCriticalSection(&csQueueLock);
-
- sprintf(szBuffer2, szContent, pECB->ConnID, dwThreadNum);
-
- // Send outgoing header
- sprintf(szBuffer, szHeader, strlen(szBuffer2));
- dwSize = strlen(szBuffer);
- pECB->ServerSupportFunction(pECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER,
- NULL, &dwSize, (unsigned long *)szBuffer);
-
- // Simulate extended processing
- Sleep(3000);
-
- // Send content
- dwSize = strlen(szBuffer2);
- pECB->WriteClient(pECB->ConnID, szBuffer2, &dwSize, 0);
-
- // Tell IIS to keep the connection open
- dwState = HSE_STATUS_SUCCESS_AND_KEEP_CONN;
- pECB->ServerSupportFunction(pECB->ConnID, HSE_REQ_DONE_WITH_SESSION, &dwState, NULL, 0);
- }
- else // No item found is unexpected condition - exit thread
- {
- LeaveCriticalSection(&csQueueLock);
- ExitThread(0);
- }
- }
- else
- break;
- }
-
- return 0;
- }
-