home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 February / CHIP_2_98.iso / software / pelne / optionp / iis4_07.cab / ThreadPool.c < prev    next >
C/C++ Source or Header  |  1997-10-25  |  3KB  |  174 lines

  1. /*++
  2.  
  3. Copyright (c) 1997  Microsoft Corporation
  4.  
  5. Module Name:    ThreadPool.c
  6.  
  7. Abstract:
  8.  
  9.     Work queue management functions.
  10.  
  11. --*/
  12.  
  13. #define WIN32_LEAN_AND_MEAN
  14. #include <windows.h>
  15. #include <httpext.h>
  16. #include "threadpool.h"
  17.  
  18.  
  19. //
  20. // Structure to create simple linked list
  21. //
  22.  
  23. typedef struct {
  24.     EXTENSION_CONTROL_BLOCK *pECB;        // Data for list entry
  25.     DWORD dwNextEntry;                    // Pointer to next entry
  26. } ECB_QUEUE_ENTRY;
  27.  
  28.  
  29. //
  30. // Array that is a simple linked list
  31. //
  32.  
  33. ECB_QUEUE_ENTRY ECBqueue[WORK_QUEUE_ENTRIES];
  34.  
  35.  
  36. //
  37. // Index of next ECBqueue entry to use, and last Entry in use.
  38. //
  39.  
  40. DWORD dwCurrentEntry, dwLastEntry;
  41.  
  42.  
  43. //
  44. // Flag to indicate that there are no other entries in the ECBqueue
  45. //
  46.  
  47. BOOL fQueueEmpty;
  48.  
  49.  
  50. BOOL 
  51. InitThreadPool(
  52.     void
  53. )
  54. /*++
  55. Purpose:
  56.  
  57.     Initialize our thread pool.
  58.  
  59. --*/
  60. {
  61.     DWORD i;
  62.     DWORD dwThreadID;
  63.  
  64.     //
  65.     // Create Semaphore in nonsignaled state
  66.     //
  67.  
  68.     if ( (hWorkSem = CreateSemaphore( NULL, 0, 0x7fffffff, NULL )) == NULL ) {
  69.         return FALSE;
  70.     }
  71.  
  72.     InitializeCriticalSection( &csQueueLock );
  73.  
  74.     fQueueEmpty = TRUE;
  75.  
  76.     //
  77.     // Create Pool Threads
  78.     //
  79.  
  80.     for ( i = 0; i < POOL_THREADS; i++ ) {
  81.         if ( CreateThread( 
  82.                 NULL, 
  83.                 0, 
  84.                 WorkerFunction, 
  85.                 (LPVOID) i, 
  86.                 0, 
  87.                 &dwThreadID
  88.                 ) == NULL ) {
  89.             return FALSE;
  90.         }
  91.     }
  92.  
  93.     //
  94.     // Clear work queue
  95.     //
  96.  
  97.     ZeroMemory( ECBqueue, WORK_QUEUE_ENTRIES * sizeof (ECB_QUEUE_ENTRY) );
  98.  
  99.  
  100.     return TRUE;
  101. }
  102.  
  103.  
  104. BOOL 
  105. AddWorkQueueEntry(
  106.     IN EXTENSION_CONTROL_BLOCK * pECB
  107. )
  108. /*++
  109.  
  110. Purpose:
  111.  
  112.     Add single work unit to the queue
  113.  
  114. Arguments:
  115.  
  116.     pECB - pointer to the extension control block
  117.  
  118. Returns:
  119.     
  120.     TRUE if the unit was successfully queued
  121.     FALSE if queue is full
  122.  
  123. --*/
  124. {
  125.     DWORD i;
  126.  
  127.     for ( i = 0; i < WORK_QUEUE_ENTRIES; i++ ) {
  128.         if ( ECBqueue[i].pECB == NULL ) {
  129.             if ( fQueueEmpty ) {
  130.                 dwCurrentEntry = i;
  131.                 fQueueEmpty = FALSE;
  132.             } else {
  133.                 ECBqueue[dwLastEntry].dwNextEntry = i;
  134.             }
  135.  
  136.             ECBqueue[i].pECB = pECB;
  137.             dwLastEntry = i;
  138.  
  139.             return TRUE;
  140.         }
  141.     }
  142.  
  143.     // If no NULL queue entry found, indicate failure
  144.     return FALSE;
  145. }
  146.  
  147. BOOL 
  148. GetWorkQueueEntry(
  149.     OUT EXTENSION_CONTROL_BLOCK ** ppECB
  150. )
  151. /*++
  152.  
  153. Purpose:
  154.  
  155. Arguments:
  156.  
  157. Returns:
  158.  
  159. --*/
  160. {
  161.     if ( (*ppECB = ECBqueue[dwCurrentEntry].pECB) == NULL ) {
  162.         return FALSE;
  163.     } else {
  164.         ECBqueue[dwCurrentEntry].pECB = NULL;
  165.         if (dwCurrentEntry == dwLastEntry)    // If this is only pending item
  166.  
  167.             fQueueEmpty = TRUE;
  168.         else
  169.             dwCurrentEntry = ECBqueue[dwCurrentEntry].dwNextEntry;
  170.     }
  171.  
  172.     return TRUE;
  173. }
  174.