A little library for making it easier to get to PASSIVE_LEVEL. Just contains

boilerplate for using work items.

svn path=/trunk/; revision=20055
This commit is contained in:
Art Yerkes 2005-12-11 08:26:16 +00:00
parent f8818e5c0a
commit 00dd460140
3 changed files with 118 additions and 0 deletions

View file

@ -0,0 +1,7 @@
<module name="chew" type="staticlibrary">
<define name="__USE_W32API" />
<define name="_NTOSKRNL_" />
<include base="chew">include</include>
<include base="reactos">w32api/include/ddk</include>
<file>workqueue.c</file>
</module>

View file

@ -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 <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;
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 );
}

View file

@ -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*/