23 #define _PH_WORKQUEUE_PRIVATE 
   60     _In_opt_ PVOID Context,
 
   68     workQueueItem->
Context = Context;
 
   78     if (WorkQueueItem->DeleteFunction)
 
   79         WorkQueueItem->DeleteFunction(WorkQueueItem->Function, WorkQueueItem->Context);
 
   88     WorkQueueItem->Function(WorkQueueItem->Context);
 
  103     _In_ ULONG MinimumThreads,
 
  104     _In_ ULONG MaximumThreads,
 
  105     _In_ ULONG NoWorkTimeout
 
  109     WorkQueue->Terminating = 
FALSE;
 
  115     WorkQueue->MinimumThreads = MinimumThreads;
 
  116     WorkQueue->MaximumThreads = MaximumThreads;
 
  117     WorkQueue->NoWorkTimeout = NoWorkTimeout;
 
  121     WorkQueue->SemaphoreHandle = NULL;
 
  122     WorkQueue->CurrentThreads = 0;
 
  123     WorkQueue->BusyCount = 0;
 
  141     PLIST_ENTRY listEntry;
 
  149     if ((index = PhFindItemList(PhDbgWorkQueueList, WorkQueue)) != -1)
 
  156     WorkQueue->Terminating = 
TRUE;
 
  159     if (WorkQueue->SemaphoreHandle)
 
  160         NtReleaseSemaphore(WorkQueue->SemaphoreHandle, WorkQueue->CurrentThreads, NULL);
 
  166     listEntry = WorkQueue->QueueListHead.Flink;
 
  168     while (listEntry != &WorkQueue->QueueListHead)
 
  171         listEntry = listEntry->Flink;
 
  175     if (WorkQueue->SemaphoreHandle)
 
  176         NtClose(WorkQueue->SemaphoreHandle);
 
  200     HANDLE semaphoreHandle;
 
  202     semaphoreHandle = WorkQueue->SemaphoreHandle;
 
  204     if (!semaphoreHandle)
 
  206         NtCreateSemaphore(&semaphoreHandle, SEMAPHORE_ALL_ACCESS, NULL, 0, MAXLONG);
 
  207         assert(semaphoreHandle);
 
  210             &WorkQueue->SemaphoreHandle,
 
  216             NtClose(semaphoreHandle);
 
  217             semaphoreHandle = WorkQueue->SemaphoreHandle;
 
  221     return semaphoreHandle;
 
  239         WorkQueue->CurrentThreads++;
 
  240         NtClose(threadHandle);
 
  261         HANDLE semaphoreHandle;
 
  262         LARGE_INTEGER timeout;
 
  268             BOOLEAN terminate = 
FALSE;
 
  292             status = NtWaitForSingleObject(
 
  300             status = STATUS_UNSUCCESSFUL;
 
  303         if (status == STATUS_WAIT_0 && !workQueue->
Terminating)
 
  305             PLIST_ENTRY listEntry;
 
  324                 _InterlockedDecrement(&workQueue->
BusyCount);
 
  331             BOOLEAN terminate = 
FALSE;
 
  353     return STATUS_SUCCESS;
 
  366     _In_opt_ PVOID Context
 
  383     _In_opt_ PVOID Context,
 
  394     _InterlockedIncrement(&WorkQueue->BusyCount);
 
  402     if (WorkQueue->BusyCount >= WorkQueue->CurrentThreads &&
 
  403         WorkQueue->CurrentThreads < WorkQueue->MaximumThreads)
 
  408         if (WorkQueue->CurrentThreads < WorkQueue->MaximumThreads)
 
  423     _In_opt_ PVOID Context