mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
- 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:
parent
13ebb47cf4
commit
3db65819eb
6 changed files with 88 additions and 119 deletions
|
@ -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(
|
||||
|
|
|
@ -11,7 +11,6 @@ typedef struct _DISCONNECT_TYPE {
|
|||
UINT Type;
|
||||
PVOID Context;
|
||||
PIRP Irp;
|
||||
PFILE_OBJECT FileObject;
|
||||
} DISCONNECT_TYPE, *PDISCONNECT_TYPE;
|
||||
|
||||
NTSTATUS DispTdiAccept(
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue