pDevExt->Specific.Library.WorkerCount = 0;
KeInitializeEvent( &pDevExt->Specific.Library.WorkerQueueHasItems,
- NotificationEvent,
+ SynchronizationEvent,
FALSE);
//
pDevExt->Specific.Library.IOWorkerCount = 0;
KeInitializeEvent( &pDevExt->Specific.Library.IOWorkerQueueHasItems,
- NotificationEvent,
+ SynchronizationEvent,
FALSE);
//
pDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
//
- // Loop through the workers shutting them down
+ // Loop through the workers shutting them down in two stages.
+ // First, clear AFS_WORKER_PROCESS_REQUESTS so that workers
+ // stop processing requests. Second, call AFSShutdownWorkerThread()
+ // to wake the workers and wait for them to exit.
//
pCurrentWorker = pDevExt->Specific.Library.PoolHead;
+ while( index < pDevExt->Specific.Library.WorkerCount)
+ {
+
+ ClearFlag( pCurrentWorker->State, AFS_WORKER_PROCESS_REQUESTS);
+
+ pCurrentWorker = pCurrentWorker->fLink;
+
+ if ( pCurrentWorker == NULL)
+ {
+
+ break;
+ }
+
+ index++;
+ }
+
+ pCurrentWorker = pDevExt->Specific.Library.PoolHead;
+
+ index = 0;
+
while( index < pDevExt->Specific.Library.WorkerCount)
{
ExDeleteResourceLite( &pDevExt->Specific.Library.QueueLock);
//
- // Loop through the IO workers shutting them down
+ // Loop through the IO workers shutting them down in two stages.
+ // First, clear AFS_WORKER_PROCESS_REQUESTS so that workers
+ // stop processing requests. Second, call AFSShutdownWorkerThread()
+ // to wake the workers and wait for them to exit.
//
pCurrentWorker = pDevExt->Specific.Library.IOPoolHead;
index = 0;
+ while( index < pDevExt->Specific.Library.IOWorkerCount)
+ {
+
+ ClearFlag( pCurrentWorker->State, AFS_WORKER_PROCESS_REQUESTS);
+
+ pCurrentWorker = pCurrentWorker->fLink;
+
+ if ( pCurrentWorker == NULL)
+ {
+
+ break;
+ }
+
+ index++;
+ }
+
+ pCurrentWorker = pDevExt->Specific.Library.IOPoolHead;
+
+ index = 0;
+
while( index < pDevExt->Specific.Library.IOWorkerCount)
{
//
// Description:
//
-// This function shusdown a worker thread in the pool
+// This function shutsdown a worker thread in the pool
//
// Return:
//
BooleanFlagOn( PoolContext->State, AFS_WORKER_INITIALIZED))
{
- //
- // Clear the 'keep processing' flag
- //
-
- ClearFlag( PoolContext->State, AFS_WORKER_PROCESS_REQUESTS);
-
//
// Wake up the thread if it is a sleep
//
BooleanFlagOn( PoolContext->State, AFS_WORKER_INITIALIZED))
{
- //
- // Clear the 'keep processing' flag
- //
-
- ClearFlag( PoolContext->State, AFS_WORKER_PROCESS_REQUESTS);
-
//
// Wake up the thread if it is a sleep
//
AFSWorkQueueContext *pPoolContext = (AFSWorkQueueContext *)Context;
AFSWorkItem *pWorkItem;
BOOLEAN freeWorkItem = TRUE;
- BOOLEAN exitThread = FALSE;
AFSDeviceExt *pLibraryDevExt = NULL;
LONG lCount;
0,
FALSE);
-
//
// Indicate we are initialized
//
SetFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
+ ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.WorkerQueueHasItems,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+
while( BooleanFlagOn( pPoolContext->State, AFS_WORKER_PROCESS_REQUESTS))
{
- ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.WorkerQueueHasItems,
- Executive,
- KernelMode,
- FALSE,
- NULL);
-
if( !NT_SUCCESS( ntStatus))
{
}
}
}
+
+ ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.WorkerQueueHasItems,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+
} // worker thread loop
+ ClearFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
+
+ // Wake up another worker so they too can exit
+
+ KeSetEvent( &pLibraryDevExt->Specific.Library.WorkerQueueHasItems,
+ 0,
+ FALSE);
+
PsTerminateSystemThread( 0);
return;
AFSWorkQueueContext *pPoolContext = (AFSWorkQueueContext *)Context;
AFSWorkItem *pWorkItem;
BOOLEAN freeWorkItem = TRUE;
- BOOLEAN exitThread = FALSE;
AFSDeviceExt *pLibraryDevExt = NULL, *pRdrDevExt = NULL;
pLibraryDevExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
SetFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
+ ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.IOWorkerQueueHasItems,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+
while( BooleanFlagOn( pPoolContext->State, AFS_WORKER_PROCESS_REQUESTS))
{
- ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.IOWorkerQueueHasItems,
- Executive,
- KernelMode,
- FALSE,
- NULL);
-
if( !NT_SUCCESS( ntStatus))
{
}
}
}
+
+ ntStatus = KeWaitForSingleObject( &pLibraryDevExt->Specific.Library.IOWorkerQueueHasItems,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+
} // worker thread loop
+ ClearFlag( pPoolContext->State, AFS_WORKER_INITIALIZED);
+
+ // Wake up another IOWorker so they too can exit
+
+ KeSetEvent( &pLibraryDevExt->Specific.Library.IOWorkerQueueHasItems,
+ 0,
+ FALSE);
+
PsTerminateSystemThread( 0);
return;
AFSWorkQueueContext *pPoolContext = (AFSWorkQueueContext *)&AFSGlobalRoot->VolumeWorkerContext;
AFSDeviceExt *pControlDeviceExt = NULL;
AFSDeviceExt *pRDRDeviceExt = NULL;
- BOOLEAN exitThread = FALSE;
LARGE_INTEGER DueTime;
LONG TimeOut;
KTIMER Timer;
{
pDevExt->Specific.Library.QueueTail = NULL;
+ }
+ else
+ {
- KeResetEvent(&(pDevExt->Specific.Library.WorkerQueueHasItems));
+ //
+ // Wake up another worker
+ //
+
+ KeSetEvent( &(pDevExt->Specific.Library.WorkerQueueHasItems),
+ 0,
+ FALSE);
}
}
- else
- {
- KeResetEvent(&(pDevExt->Specific.Library.WorkerQueueHasItems));
- }
AFSReleaseResource( &pDevExt->Specific.Library.QueueLock);
{
pDevExt->Specific.Library.IOQueueTail = NULL;
+ }
+ else
+ {
- KeResetEvent(&(pDevExt->Specific.Library.IOWorkerQueueHasItems));
+ //
+ // Wake up another worker
+ //
+
+ KeSetEvent( &(pDevExt->Specific.Library.IOWorkerQueueHasItems),
+ 0,
+ FALSE);
}
}
- else
- {
- KeResetEvent(&(pDevExt->Specific.Library.IOWorkerQueueHasItems));
- }
AFSReleaseResource( &pDevExt->Specific.Library.IOQueueLock);