mirror of
https://github.com/reactos/reactos.git
synced 2024-10-22 05:46:19 +00:00
c501d8112c
svn path=/branches/aicom-network-fixes/; revision=34994
107 lines
2.6 KiB
C
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 );
|
|
}
|