From 3db65819eba8534c8ea93b05135e8a607d1d5ba3 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 19 Sep 2009 00:58:36 +0000 Subject: [PATCH] - Partial rewrite of CHEW - Remove some unneeded work item usage - Remove an unused member of DISCONNECT_TYPE svn path=/trunk/; revision=43076 --- reactos/drivers/network/tcpip/datalink/lan.c | 17 +-- .../drivers/network/tcpip/include/dispatch.h | 1 - .../drivers/network/tcpip/tcpip/dispatch.c | 28 ++--- reactos/include/reactos/chew/chew.h | 18 +-- reactos/lib/drivers/chew/workqueue.c | 105 +++++++----------- reactos/lib/drivers/ip/transport/tcp/tcp.c | 38 ++++--- 6 files changed, 88 insertions(+), 119 deletions(-) diff --git a/reactos/drivers/network/tcpip/datalink/lan.c b/reactos/drivers/network/tcpip/datalink/lan.c index b77aaf888d6..d813ec8d293 100644 --- a/reactos/drivers/network/tcpip/datalink/lan.c +++ b/reactos/drivers/network/tcpip/datalink/lan.c @@ -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( diff --git a/reactos/drivers/network/tcpip/include/dispatch.h b/reactos/drivers/network/tcpip/include/dispatch.h index b6aada9058a..f9344252a8a 100644 --- a/reactos/drivers/network/tcpip/include/dispatch.h +++ b/reactos/drivers/network/tcpip/include/dispatch.h @@ -11,7 +11,6 @@ typedef struct _DISCONNECT_TYPE { UINT Type; PVOID Context; PIRP Irp; - PFILE_OBJECT FileObject; } DISCONNECT_TYPE, *PDISCONNECT_TYPE; NTSTATUS DispTdiAccept( diff --git a/reactos/drivers/network/tcpip/tcpip/dispatch.c b/reactos/drivers/network/tcpip/tcpip/dispatch.c index 06ffa1bc190..237149520b3 100644 --- a/reactos/drivers/network/tcpip/tcpip/dispatch.c +++ b/reactos/drivers/network/tcpip/tcpip/dispatch.c @@ -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: diff --git a/reactos/include/reactos/chew/chew.h b/reactos/include/reactos/chew/chew.h index 9dfd9e94066..16b8ae9f9bc 100644 --- a/reactos/include/reactos/chew/chew.h +++ b/reactos/include/reactos/chew/chew.h @@ -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*/ diff --git a/reactos/lib/drivers/chew/workqueue.c b/reactos/lib/drivers/chew/workqueue.c index 1df42e22285..978e5a41ed4 100644 --- a/reactos/lib/drivers/chew/workqueue.c +++ b/reactos/lib/drivers/chew/workqueue.c @@ -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 ); -} diff --git a/reactos/lib/drivers/ip/transport/tcp/tcp.c b/reactos/lib/drivers/ip/transport/tcp/tcp.c index 17a80ab91db..23bbb1c8df9 100644 --- a/reactos/lib/drivers/ip/transport/tcp/tcp.c +++ b/reactos/lib/drivers/ip/transport/tcp/tcp.c @@ -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,