reactos/lib/drivers/chew/workqueue.c
Art Yerkes c501d8112c Create a branch for network fixes.
svn path=/branches/aicom-network-fixes/; revision=34994
2008-08-01 11:32:26 +00:00

107 lines
2.6 KiB
C

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/lib/chew/workqueue.c
* PURPOSE: Common Highlevel Executive Worker
*
* PROGRAMMERS: arty (ayerkes@speakeasy.net)
*/
#include <ntddk.h>
#include <chew/chew.h>
#define NDEBUG
#define FOURCC(w,x,y,z) (((w) << 24) | ((x) << 16) | ((y) << 8) | (z))
PDEVICE_OBJECT WorkQueueDevice;
LIST_ENTRY WorkQueue;
KSPIN_LOCK WorkQueueLock;
typedef struct _WORK_ITEM {
LIST_ENTRY Entry;
PIO_WORKITEM WorkItem;
VOID (*Worker)( PVOID Data );
CHAR UserSpace[1];
} WORK_ITEM, *PWORK_ITEM;
VOID ChewInit( PDEVICE_OBJECT DeviceObject ) {
WorkQueueDevice = DeviceObject;
InitializeListHead( &WorkQueue );
KeInitializeSpinLock( &WorkQueueLock );
}
VOID ChewShutdown() {
KIRQL OldIrql;
PLIST_ENTRY Entry;
PWORK_ITEM WorkItem;
KeAcquireSpinLock( &WorkQueueLock, &OldIrql );
while( !IsListEmpty( &WorkQueue ) ) {
Entry = RemoveHeadList( &WorkQueue );
WorkItem = CONTAINING_RECORD( Entry, WORK_ITEM, Entry );
IoFreeWorkItem( WorkItem->WorkItem );
ExFreePool( WorkItem );
}
KeReleaseSpinLock( &WorkQueueLock, OldIrql );
}
VOID STDCALL ChewWorkItem( PDEVICE_OBJECT DeviceObject, PVOID ChewItem ) {
PWORK_ITEM WorkItem = ChewItem;
RemoveEntryList( &WorkItem->Entry );
if( WorkItem->Worker )
WorkItem->Worker( WorkItem->UserSpace );
IoFreeWorkItem( WorkItem->WorkItem );
ExFreePool( WorkItem );
}
BOOLEAN ChewCreate
( PVOID *ItemPtr, SIZE_T Bytes, VOID (*Worker)( PVOID ), PVOID UserSpace ) {
PWORK_ITEM Item;
if( KeGetCurrentIrql() == PASSIVE_LEVEL ) {
if( ItemPtr )
*ItemPtr = NULL;
Worker(UserSpace);
return TRUE;
} else {
Item = ExAllocatePoolWithTag
( NonPagedPool,
sizeof( WORK_ITEM ) + Bytes - 1,
FOURCC('C','H','E','W') );
if( Item ) {
Item->WorkItem = IoAllocateWorkItem( WorkQueueDevice );
if( !Item->WorkItem ) {
ExFreePool( Item );
return FALSE;
}
Item->Worker = Worker;
if( Bytes && UserSpace )
RtlCopyMemory( Item->UserSpace, UserSpace, Bytes );
ExInterlockedInsertTailList
( &WorkQueue, &Item->Entry, &WorkQueueLock );
IoQueueWorkItem
( Item->WorkItem, ChewWorkItem, CriticalWorkQueue, Item );
if( ItemPtr )
*ItemPtr = Item;
return TRUE;
} else {
return FALSE;
}
}
}
VOID ChewRemove( PVOID Item ) {
PWORK_ITEM WorkItem = Item;
IoFreeWorkItem( WorkItem->WorkItem );
ExFreePool( WorkItem );
}