diff --git a/reactos/drivers/lib/chew/chew.xml b/reactos/drivers/lib/chew/chew.xml new file mode 100644 index 00000000000..15984175490 --- /dev/null +++ b/reactos/drivers/lib/chew/chew.xml @@ -0,0 +1,7 @@ + + + + include + w32api/include/ddk + workqueue.c + \ No newline at end of file diff --git a/reactos/drivers/lib/chew/workqueue.c b/reactos/drivers/lib/chew/workqueue.c new file mode 100644 index 00000000000..1f041bcb9c9 --- /dev/null +++ b/reactos/drivers/lib/chew/workqueue.c @@ -0,0 +1,101 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS TCP/IP protocol driver + * FILE: tcpip/main.c + * PURPOSE: Common Highlevel Executive Worker + * PROGRAMMERS: Art Yerkes + * REVISIONS: + * CSH 10/12-2005 Created + */ +#include +#include + +//#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; + + if( WorkItem->Worker ) + WorkItem->Worker( WorkItem->UserSpace ); + + IoFreeWorkItem( WorkItem->WorkItem ); + ExFreePool( WorkItem ); +} + +BOOLEAN ChewCreate +( PVOID *ItemPtr, UINT Bytes, VOID (*Worker)( PVOID ), PVOID UserSpace ) { + PWORK_ITEM Item; + if( KeGetCurrentIrql() == PASSIVE_LEVEL ) { + *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 ); + + *ItemPtr = Item; + + return TRUE; + } else + return FALSE; + } +} + +VOID ChewRemove( PVOID Item ) { + PWORK_ITEM WorkItem = Item; + IoFreeWorkItem( WorkItem->WorkItem ); + ExFreePool( WorkItem ); +} diff --git a/reactos/include/chew/chew.h b/reactos/include/chew/chew.h new file mode 100644 index 00000000000..d87eb8293e9 --- /dev/null +++ b/reactos/include/chew/chew.h @@ -0,0 +1,10 @@ +#ifndef _REACTOS_CHEW_H +#define _REACTOS_CHEW_H + +VOID ChewInit( PDEVICE_OBJECT DeviceObject ); +VOID ChewShutdown(); +BOOLEAN ChewCreate +( PVOID *Item, UINT Bytes, VOID (*Worker)(PVOID), PVOID UserSpace ); +VOID ChewRemove( PVOID Item ); + +#endif/*_REACTOS_CHEW_H*/