- Partial rewrite of CHEW

- Remove some unneeded work item usage
 - Remove an unused member of DISCONNECT_TYPE

svn path=/trunk/; revision=43076
This commit is contained in:
Cameron Gutman 2009-09-19 00:58:36 +00:00
parent 13ebb47cf4
commit 3db65819eb
6 changed files with 88 additions and 119 deletions

View file

@ -254,6 +254,8 @@ VOID LanReceiveWorker( PVOID Context ) {
Adapter = WorkItem->Adapter;
BytesTransferred = WorkItem->BytesTransferred;
exFreePool(WorkItem);
IPInitializePacket(&IPPacket, 0);
IPPacket.NdisPacket = Packet;
@ -303,18 +305,19 @@ VOID LanSubmitReceiveWork(
PNDIS_PACKET Packet,
NDIS_STATUS Status,
UINT BytesTransferred) {
LAN_WQ_ITEM WQItem;
PLAN_WQ_ITEM WQItem = exAllocatePool(NonPagedPool, sizeof(LAN_WQ_ITEM));
PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
TI_DbgPrint(DEBUG_DATALINK,("called\n"));
WQItem.Packet = Packet;
WQItem.Adapter = Adapter;
WQItem.BytesTransferred = BytesTransferred;
if (!WQItem) return;
if( !ChewCreate
( NULL, sizeof(LAN_WQ_ITEM), LanReceiveWorker, &WQItem ) )
ASSERT(0);
WQItem->Packet = Packet;
WQItem->Adapter = Adapter;
WQItem->BytesTransferred = BytesTransferred;
if (!ChewCreate( LanReceiveWorker, WQItem ))
exFreePool(WQItem);
}
VOID NTAPI ProtocolTransferDataComplete(

View file

@ -11,7 +11,6 @@ typedef struct _DISCONNECT_TYPE {
UINT Type;
PVOID Context;
PIRP Irp;
PFILE_OBJECT FileObject;
} DISCONNECT_TYPE, *PDISCONNECT_TYPE;
NTSTATUS DispTdiAccept(

View file

@ -118,6 +118,8 @@ VOID DispDoDisconnect( PVOID Data ) {
TI_DbgPrint(DEBUG_IRP, ("PostCancel: DoDisconnect done\n"));
DispDataRequestComplete(DisType->Irp, STATUS_CANCELLED, 0);
exFreePool(DisType);
}
VOID NTAPI DispCancelRequest(
@ -134,9 +136,7 @@ VOID NTAPI DispCancelRequest(
PTRANSPORT_CONTEXT TranContext;
PFILE_OBJECT FileObject;
UCHAR MinorFunction;
DISCONNECT_TYPE DisType;
PVOID WorkItem;
/*NTSTATUS Status = STATUS_SUCCESS;*/
PDISCONNECT_TYPE DisType;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
@ -159,19 +159,21 @@ VOID NTAPI DispCancelRequest(
switch(MinorFunction) {
case TDI_SEND:
case TDI_RECEIVE:
DisType.Type = TDI_DISCONNECT_RELEASE |
((MinorFunction == TDI_RECEIVE) ? TDI_DISCONNECT_ABORT : 0);
DisType.Context = TranContext->Handle.ConnectionContext;
DisType.Irp = Irp;
DisType.FileObject = FileObject;
DisType = exAllocatePool(NonPagedPool, sizeof(DISCONNECT_TYPE));
if (DisType)
{
DisType->Type = TDI_DISCONNECT_RELEASE |
((MinorFunction == TDI_RECEIVE) ? TDI_DISCONNECT_ABORT : 0);
DisType->Context = TranContext->Handle.ConnectionContext;
DisType->Irp = Irp;
TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp );
TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp );
if (!ChewCreate(DispDoDisconnect, DisType))
exFreePool(DisType);
}
IoReleaseCancelSpinLock(Irp->CancelIrql);
if( !ChewCreate( &WorkItem, sizeof(DISCONNECT_TYPE),
DispDoDisconnect, &DisType ) )
ASSERT(0);
return;
case TDI_SEND_DATAGRAM:

View file

@ -16,25 +16,13 @@
*/
VOID ChewInit( PDEVICE_OBJECT DeviceObject );
/**
* Shutdown CHEW, including removing remaining work items.
* Shutdown CHEW, waits for remaining work items.
*/
VOID ChewShutdown();
/**
* Create a work item, or perform the work, based on IRQL.
* At passive level, Worker is called directly on UserSpace.
* At greater than passive level, a work item is created with Bytes
* context area and data copied from UserSpace.
* If a work item is created, Item contains the address and the function
* returns true.
* If the work is performed immediately, Item contains NULL and the
* function returns true.
* Else, the function returns false and Item is undefined.
* Creates and queues a work item.
*/
BOOLEAN ChewCreate
( PVOID *Item, SIZE_T Bytes, VOID (*Worker)(PVOID), PVOID UserSpace );
/**
* Remove a work item, given the pointer returned to Item in ChewCreate.
*/
VOID ChewRemove( PVOID Item );
( VOID (*Worker)(PVOID), PVOID WorkerContext );
#endif/*_REACTOS_CHEW_H*/

View file

@ -11,97 +11,72 @@
#define NDEBUG
#define FOURCC(w,x,y,z) (((w) << 24) | ((x) << 16) | ((y) << 8) | (z))
#define FOURCC(w,x,y,z) (((w) << 24) | ((x) << 16) | ((y) << 8) | (z))
#define CHEW_TAG FOURCC('C','H','E','W')
PDEVICE_OBJECT WorkQueueDevice;
LIST_ENTRY WorkQueue;
KSPIN_LOCK WorkQueueLock;
KSPIN_LOCK WorkQueueLock;
KEVENT WorkQueueClear;
typedef struct _WORK_ITEM {
LIST_ENTRY Entry;
PIO_WORKITEM WorkItem;
VOID (*Worker)( PVOID Data );
CHAR UserSpace[1];
VOID (*Worker)( PVOID WorkerContext );
PVOID WorkerContext;
} WORK_ITEM, *PWORK_ITEM;
VOID ChewInit( PDEVICE_OBJECT DeviceObject ) {
WorkQueueDevice = DeviceObject;
InitializeListHead( &WorkQueue );
KeInitializeSpinLock( &WorkQueueLock );
KeInitializeSpinLock( &WorkQueueLock );
KeInitializeEvent(&WorkQueueClear, NotificationEvent, TRUE);
}
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 );
KeWaitForSingleObject(&WorkQueueClear, Executive, KernelMode, FALSE, NULL);
}
VOID NTAPI ChewWorkItem( PDEVICE_OBJECT DeviceObject, PVOID ChewItem ) {
PWORK_ITEM WorkItem = ChewItem;
PWORK_ITEM WorkItem = ChewItem;
KIRQL OldIrql;
RemoveEntryList( &WorkItem->Entry );
WorkItem->Worker( WorkItem->WorkerContext );
if( WorkItem->Worker )
WorkItem->Worker( WorkItem->UserSpace );
IoFreeWorkItem( WorkItem->WorkItem );
ExFreePool( WorkItem );
IoFreeWorkItem( WorkItem->WorkItem );
KeAcquireSpinLock(&WorkQueueLock, &OldIrql);
RemoveEntryList(&WorkItem->Entry);
if (IsListEmpty(&WorkQueue))
KeSetEvent(&WorkQueueClear, 0, FALSE);
KeReleaseSpinLock(&WorkQueueLock, OldIrql);
ExFreePoolWithTag(WorkItem, CHEW_TAG);
}
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
( VOID (*Worker)( PVOID ), PVOID WorkerContext ) {
PWORK_ITEM Item;
Item = ExAllocatePoolWithTag
( NonPagedPool,
sizeof( WORK_ITEM ) + Bytes - 1,
FOURCC('C','H','E','W') );
sizeof( WORK_ITEM ),
CHEW_TAG );
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, DelayedWorkQueue, Item );
if( ItemPtr )
*ItemPtr = Item;
return TRUE;
} else {
if( Item ) {
Item->WorkItem = IoAllocateWorkItem( WorkQueueDevice );
if( !Item->WorkItem ) {
ExFreePool( Item );
return FALSE;
}
Item->Worker = Worker;
Item->WorkerContext = WorkerContext;
ExInterlockedInsertTailList( &WorkQueue, &Item->Entry, &WorkQueueLock );
KeResetEvent(&WorkQueueClear);
IoQueueWorkItem( Item->WorkItem, ChewWorkItem, DelayedWorkQueue, Item );
return TRUE;
} else {
return FALSE;
}
}
VOID ChewRemove( PVOID Item ) {
PWORK_ITEM WorkItem = Item;
RemoveEntryList( &WorkItem->Entry );
IoFreeWorkItem( WorkItem->WorkItem );
ExFreePool( WorkItem );
}

View file

@ -41,39 +41,41 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) {
while ((Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest,
&Connection->Lock )) != NULL)
{
DISCONNECT_TYPE DisType;
PIO_STACK_LOCATION IrpSp;
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
Complete = Bucket->Request.RequestNotifyObject;
IrpSp = IoGetCurrentIrpStackLocation((PIRP)Bucket->Request.RequestContext);
/* We have to notify oskittcp of the abortion */
DisType.Type = TDI_DISCONNECT_RELEASE | TDI_DISCONNECT_ABORT;
DisType.Context = Connection;
DisType.Irp = (PIRP)Bucket->Request.RequestContext;
DisType.FileObject = IrpSp->FileObject;
TCPDisconnect
( Connection,
TDI_DISCONNECT_RELEASE | TDI_DISCONNECT_ABORT,
NULL,
NULL,
Bucket->Request.RequestNotifyObject,
(PIRP)Bucket->Request.RequestContext );
ChewCreate(NULL, sizeof(DISCONNECT_TYPE),
DispDoDisconnect, &DisType);
Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
exFreePool(Bucket);
}
while ((Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest,
&Connection->Lock )) != NULL)
{
DISCONNECT_TYPE DisType;
PIO_STACK_LOCATION IrpSp;
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
Complete = Bucket->Request.RequestNotifyObject;
IrpSp = IoGetCurrentIrpStackLocation((PIRP)Bucket->Request.RequestContext);
/* We have to notify oskittcp of the abortion */
DisType.Type = TDI_DISCONNECT_RELEASE;
DisType.Context = Connection;
DisType.Irp = (PIRP)Bucket->Request.RequestContext;
DisType.FileObject = IrpSp->FileObject;
TCPDisconnect
( Connection,
TDI_DISCONNECT_RELEASE,
NULL,
NULL,
Bucket->Request.RequestNotifyObject,
(PIRP)Bucket->Request.RequestContext );
ChewCreate(NULL, sizeof(DISCONNECT_TYPE),
DispDoDisconnect, &DisType);
Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
exFreePool(Bucket);
}
while ((Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest,