2025-11-28 00:35:46 +09:00

134 lines
2.2 KiB
C

/* Copyright (c) 1997-2002 Microsoft Corporation
Module Name:
ThreadPool.c
Abstract:
Work queue management functions.
*/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <httpext.h>
#include "threadpool.h"
/* Structure to create simple linked list */
typedef struct {
EXTENSION_CONTROL_BLOCK *pECB; /* Data for list entry */
DWORD dwNextEntry; /* Pointer to next entry */
} ECB_QUEUE_ENTRY;
/* Array that is a simple linked list */
ECB_QUEUE_ENTRY ECBqueue[WORK_QUEUE_ENTRIES];
/* Index of next ECBqueue entry to use, and last Entry in use. */
DWORD dwCurrentEntry, dwLastEntry;
/* Flag to indicate that there are no other entries in the ECBqueue */
BOOL fQueueEmpty;
/*
Description:
Initialize our thread pool
*/
BOOL InitThreadPool(void)
{
DWORD i;
DWORD dwThreadID;
/* Create Semaphore in nonsignaled state */
if ((hWorkSem = CreateSemaphore(NULL, 0, 0x7fffffff, NULL)) == NULL)
return FALSE;
InitializeCriticalSection(&csQueueLock);
fQueueEmpty = TRUE;
/* Create Pool Threads */
for (i = 0; i < POOL_THREADS; i++)
if (CreateThread(NULL, 0, WorkerFunction, (LPVOID)i, 0, &dwThreadID) == NULL)
return FALSE;
/* Clear work queue */
ZeroMemory(ECBqueue, WORK_QUEUE_ENTRIES * sizeof(ECB_QUEUE_ENTRY));
return TRUE;
}
/*
Description:
Add single work unit to the queue
Arguments:
pECB - pointer to the extension control block
Returns:
TRUE if the unit was successfully queued
FALSE if queue is full
*/
BOOL AddWorkQueueEntry(IN EXTENSION_CONTROL_BLOCK *pECB)
{
DWORD i;
for (i = 0; i < WORK_QUEUE_ENTRIES; i++) {
if (ECBqueue[i].pECB == NULL) {
if (fQueueEmpty) {
dwCurrentEntry = i;
fQueueEmpty = FALSE;
} else {
ECBqueue[dwLastEntry].dwNextEntry = i;
}
ECBqueue[i].pECB = pECB;
dwLastEntry = i;
return TRUE;
}
}
/* If no NULL queue entry found, indicate failure */
return FALSE;
}
BOOL GetWorkQueueEntry(OUT EXTENSION_CONTROL_BLOCK **ppECB)
{
if ((*ppECB = ECBqueue[dwCurrentEntry].pECB) == NULL) {
return FALSE;
} else {
ECBqueue[dwCurrentEntry].pECB = NULL;
if (dwCurrentEntry == dwLastEntry) /* If this is only pending item */
fQueueEmpty = TRUE;
else
dwCurrentEntry = ECBqueue[dwCurrentEntry].dwNextEntry;
}
return TRUE;
}