mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 16:02:56 +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;
|
Adapter = WorkItem->Adapter;
|
||||||
BytesTransferred = WorkItem->BytesTransferred;
|
BytesTransferred = WorkItem->BytesTransferred;
|
||||||
|
|
||||||
|
exFreePool(WorkItem);
|
||||||
|
|
||||||
IPInitializePacket(&IPPacket, 0);
|
IPInitializePacket(&IPPacket, 0);
|
||||||
|
|
||||||
IPPacket.NdisPacket = Packet;
|
IPPacket.NdisPacket = Packet;
|
||||||
|
@ -303,18 +305,19 @@ VOID LanSubmitReceiveWork(
|
||||||
PNDIS_PACKET Packet,
|
PNDIS_PACKET Packet,
|
||||||
NDIS_STATUS Status,
|
NDIS_STATUS Status,
|
||||||
UINT BytesTransferred) {
|
UINT BytesTransferred) {
|
||||||
LAN_WQ_ITEM WQItem;
|
PLAN_WQ_ITEM WQItem = exAllocatePool(NonPagedPool, sizeof(LAN_WQ_ITEM));
|
||||||
PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
|
PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_DATALINK,("called\n"));
|
TI_DbgPrint(DEBUG_DATALINK,("called\n"));
|
||||||
|
|
||||||
WQItem.Packet = Packet;
|
if (!WQItem) return;
|
||||||
WQItem.Adapter = Adapter;
|
|
||||||
WQItem.BytesTransferred = BytesTransferred;
|
|
||||||
|
|
||||||
if( !ChewCreate
|
WQItem->Packet = Packet;
|
||||||
( NULL, sizeof(LAN_WQ_ITEM), LanReceiveWorker, &WQItem ) )
|
WQItem->Adapter = Adapter;
|
||||||
ASSERT(0);
|
WQItem->BytesTransferred = BytesTransferred;
|
||||||
|
|
||||||
|
if (!ChewCreate( LanReceiveWorker, WQItem ))
|
||||||
|
exFreePool(WQItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID NTAPI ProtocolTransferDataComplete(
|
VOID NTAPI ProtocolTransferDataComplete(
|
||||||
|
|
|
@ -11,7 +11,6 @@ typedef struct _DISCONNECT_TYPE {
|
||||||
UINT Type;
|
UINT Type;
|
||||||
PVOID Context;
|
PVOID Context;
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
PFILE_OBJECT FileObject;
|
|
||||||
} DISCONNECT_TYPE, *PDISCONNECT_TYPE;
|
} DISCONNECT_TYPE, *PDISCONNECT_TYPE;
|
||||||
|
|
||||||
NTSTATUS DispTdiAccept(
|
NTSTATUS DispTdiAccept(
|
||||||
|
|
|
@ -118,6 +118,8 @@ VOID DispDoDisconnect( PVOID Data ) {
|
||||||
TI_DbgPrint(DEBUG_IRP, ("PostCancel: DoDisconnect done\n"));
|
TI_DbgPrint(DEBUG_IRP, ("PostCancel: DoDisconnect done\n"));
|
||||||
|
|
||||||
DispDataRequestComplete(DisType->Irp, STATUS_CANCELLED, 0);
|
DispDataRequestComplete(DisType->Irp, STATUS_CANCELLED, 0);
|
||||||
|
|
||||||
|
exFreePool(DisType);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID NTAPI DispCancelRequest(
|
VOID NTAPI DispCancelRequest(
|
||||||
|
@ -134,9 +136,7 @@ VOID NTAPI DispCancelRequest(
|
||||||
PTRANSPORT_CONTEXT TranContext;
|
PTRANSPORT_CONTEXT TranContext;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
UCHAR MinorFunction;
|
UCHAR MinorFunction;
|
||||||
DISCONNECT_TYPE DisType;
|
PDISCONNECT_TYPE DisType;
|
||||||
PVOID WorkItem;
|
|
||||||
/*NTSTATUS Status = STATUS_SUCCESS;*/
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
|
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
|
||||||
|
|
||||||
|
@ -159,19 +159,21 @@ VOID NTAPI DispCancelRequest(
|
||||||
switch(MinorFunction) {
|
switch(MinorFunction) {
|
||||||
case TDI_SEND:
|
case TDI_SEND:
|
||||||
case TDI_RECEIVE:
|
case TDI_RECEIVE:
|
||||||
DisType.Type = TDI_DISCONNECT_RELEASE |
|
DisType = exAllocatePool(NonPagedPool, sizeof(DISCONNECT_TYPE));
|
||||||
|
if (DisType)
|
||||||
|
{
|
||||||
|
DisType->Type = TDI_DISCONNECT_RELEASE |
|
||||||
((MinorFunction == TDI_RECEIVE) ? TDI_DISCONNECT_ABORT : 0);
|
((MinorFunction == TDI_RECEIVE) ? TDI_DISCONNECT_ABORT : 0);
|
||||||
DisType.Context = TranContext->Handle.ConnectionContext;
|
DisType->Context = TranContext->Handle.ConnectionContext;
|
||||||
DisType.Irp = Irp;
|
DisType->Irp = Irp;
|
||||||
DisType.FileObject = FileObject;
|
|
||||||
|
|
||||||
TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp );
|
TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp );
|
||||||
|
|
||||||
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
if (!ChewCreate(DispDoDisconnect, DisType))
|
||||||
|
exFreePool(DisType);
|
||||||
|
}
|
||||||
|
|
||||||
if( !ChewCreate( &WorkItem, sizeof(DISCONNECT_TYPE),
|
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
||||||
DispDoDisconnect, &DisType ) )
|
|
||||||
ASSERT(0);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case TDI_SEND_DATAGRAM:
|
case TDI_SEND_DATAGRAM:
|
||||||
|
|
|
@ -16,25 +16,13 @@
|
||||||
*/
|
*/
|
||||||
VOID ChewInit( PDEVICE_OBJECT DeviceObject );
|
VOID ChewInit( PDEVICE_OBJECT DeviceObject );
|
||||||
/**
|
/**
|
||||||
* Shutdown CHEW, including removing remaining work items.
|
* Shutdown CHEW, waits for remaining work items.
|
||||||
*/
|
*/
|
||||||
VOID ChewShutdown();
|
VOID ChewShutdown();
|
||||||
/**
|
/**
|
||||||
* Create a work item, or perform the work, based on IRQL.
|
* Creates and queues a work item.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
BOOLEAN ChewCreate
|
BOOLEAN ChewCreate
|
||||||
( PVOID *Item, SIZE_T Bytes, VOID (*Worker)(PVOID), PVOID UserSpace );
|
( VOID (*Worker)(PVOID), PVOID WorkerContext );
|
||||||
/**
|
|
||||||
* Remove a work item, given the pointer returned to Item in ChewCreate.
|
|
||||||
*/
|
|
||||||
VOID ChewRemove( PVOID Item );
|
|
||||||
|
|
||||||
#endif/*_REACTOS_CHEW_H*/
|
#endif/*_REACTOS_CHEW_H*/
|
||||||
|
|
|
@ -12,67 +12,56 @@
|
||||||
#define NDEBUG
|
#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;
|
PDEVICE_OBJECT WorkQueueDevice;
|
||||||
LIST_ENTRY WorkQueue;
|
LIST_ENTRY WorkQueue;
|
||||||
KSPIN_LOCK WorkQueueLock;
|
KSPIN_LOCK WorkQueueLock;
|
||||||
|
KEVENT WorkQueueClear;
|
||||||
|
|
||||||
typedef struct _WORK_ITEM {
|
typedef struct _WORK_ITEM {
|
||||||
LIST_ENTRY Entry;
|
LIST_ENTRY Entry;
|
||||||
PIO_WORKITEM WorkItem;
|
PIO_WORKITEM WorkItem;
|
||||||
VOID (*Worker)( PVOID Data );
|
VOID (*Worker)( PVOID WorkerContext );
|
||||||
CHAR UserSpace[1];
|
PVOID WorkerContext;
|
||||||
} WORK_ITEM, *PWORK_ITEM;
|
} WORK_ITEM, *PWORK_ITEM;
|
||||||
|
|
||||||
VOID ChewInit( PDEVICE_OBJECT DeviceObject ) {
|
VOID ChewInit( PDEVICE_OBJECT DeviceObject ) {
|
||||||
WorkQueueDevice = DeviceObject;
|
WorkQueueDevice = DeviceObject;
|
||||||
InitializeListHead( &WorkQueue );
|
InitializeListHead( &WorkQueue );
|
||||||
KeInitializeSpinLock( &WorkQueueLock );
|
KeInitializeSpinLock( &WorkQueueLock );
|
||||||
|
KeInitializeEvent(&WorkQueueClear, NotificationEvent, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID ChewShutdown() {
|
VOID ChewShutdown() {
|
||||||
KIRQL OldIrql;
|
KeWaitForSingleObject(&WorkQueueClear, Executive, KernelMode, FALSE, NULL);
|
||||||
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 NTAPI ChewWorkItem( PDEVICE_OBJECT DeviceObject, PVOID ChewItem ) {
|
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 );
|
IoFreeWorkItem( WorkItem->WorkItem );
|
||||||
ExFreePool( WorkItem );
|
|
||||||
|
KeAcquireSpinLock(&WorkQueueLock, &OldIrql);
|
||||||
|
RemoveEntryList(&WorkItem->Entry);
|
||||||
|
|
||||||
|
if (IsListEmpty(&WorkQueue))
|
||||||
|
KeSetEvent(&WorkQueueClear, 0, FALSE);
|
||||||
|
KeReleaseSpinLock(&WorkQueueLock, OldIrql);
|
||||||
|
|
||||||
|
ExFreePoolWithTag(WorkItem, CHEW_TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN ChewCreate
|
BOOLEAN ChewCreate
|
||||||
( PVOID *ItemPtr, SIZE_T Bytes, VOID (*Worker)( PVOID ), PVOID UserSpace ) {
|
( VOID (*Worker)( PVOID ), PVOID WorkerContext ) {
|
||||||
PWORK_ITEM Item;
|
PWORK_ITEM Item;
|
||||||
|
|
||||||
if( KeGetCurrentIrql() == PASSIVE_LEVEL ) {
|
|
||||||
if( ItemPtr )
|
|
||||||
*ItemPtr = NULL;
|
|
||||||
Worker(UserSpace);
|
|
||||||
return TRUE;
|
|
||||||
} else {
|
|
||||||
Item = ExAllocatePoolWithTag
|
Item = ExAllocatePoolWithTag
|
||||||
( NonPagedPool,
|
( NonPagedPool,
|
||||||
sizeof( WORK_ITEM ) + Bytes - 1,
|
sizeof( WORK_ITEM ),
|
||||||
FOURCC('C','H','E','W') );
|
CHEW_TAG );
|
||||||
|
|
||||||
if( Item ) {
|
if( Item ) {
|
||||||
Item->WorkItem = IoAllocateWorkItem( WorkQueueDevice );
|
Item->WorkItem = IoAllocateWorkItem( WorkQueueDevice );
|
||||||
|
@ -81,27 +70,13 @@ BOOLEAN ChewCreate
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
Item->Worker = Worker;
|
Item->Worker = Worker;
|
||||||
if( Bytes && UserSpace )
|
Item->WorkerContext = WorkerContext;
|
||||||
RtlCopyMemory( Item->UserSpace, UserSpace, Bytes );
|
ExInterlockedInsertTailList( &WorkQueue, &Item->Entry, &WorkQueueLock );
|
||||||
|
KeResetEvent(&WorkQueueClear);
|
||||||
ExInterlockedInsertTailList
|
IoQueueWorkItem( Item->WorkItem, ChewWorkItem, DelayedWorkQueue, Item );
|
||||||
( &WorkQueue, &Item->Entry, &WorkQueueLock );
|
|
||||||
IoQueueWorkItem
|
|
||||||
( Item->WorkItem, ChewWorkItem, DelayedWorkQueue, Item );
|
|
||||||
|
|
||||||
if( ItemPtr )
|
|
||||||
*ItemPtr = Item;
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} else {
|
} else {
|
||||||
return FALSE;
|
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,
|
while ((Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest,
|
||||||
&Connection->Lock )) != NULL)
|
&Connection->Lock )) != NULL)
|
||||||
{
|
{
|
||||||
DISCONNECT_TYPE DisType;
|
|
||||||
PIO_STACK_LOCATION IrpSp;
|
|
||||||
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
|
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
|
||||||
Complete = Bucket->Request.RequestNotifyObject;
|
Complete = Bucket->Request.RequestNotifyObject;
|
||||||
IrpSp = IoGetCurrentIrpStackLocation((PIRP)Bucket->Request.RequestContext);
|
|
||||||
|
|
||||||
/* We have to notify oskittcp of the abortion */
|
/* We have to notify oskittcp of the abortion */
|
||||||
DisType.Type = TDI_DISCONNECT_RELEASE | TDI_DISCONNECT_ABORT;
|
TCPDisconnect
|
||||||
DisType.Context = Connection;
|
( Connection,
|
||||||
DisType.Irp = (PIRP)Bucket->Request.RequestContext;
|
TDI_DISCONNECT_RELEASE | TDI_DISCONNECT_ABORT,
|
||||||
DisType.FileObject = IrpSp->FileObject;
|
NULL,
|
||||||
|
NULL,
|
||||||
|
Bucket->Request.RequestNotifyObject,
|
||||||
|
(PIRP)Bucket->Request.RequestContext );
|
||||||
|
|
||||||
ChewCreate(NULL, sizeof(DISCONNECT_TYPE),
|
Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
|
||||||
DispDoDisconnect, &DisType);
|
|
||||||
|
exFreePool(Bucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest,
|
while ((Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest,
|
||||||
&Connection->Lock )) != NULL)
|
&Connection->Lock )) != NULL)
|
||||||
{
|
{
|
||||||
DISCONNECT_TYPE DisType;
|
|
||||||
PIO_STACK_LOCATION IrpSp;
|
|
||||||
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
|
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
|
||||||
Complete = Bucket->Request.RequestNotifyObject;
|
Complete = Bucket->Request.RequestNotifyObject;
|
||||||
IrpSp = IoGetCurrentIrpStackLocation((PIRP)Bucket->Request.RequestContext);
|
|
||||||
|
|
||||||
/* We have to notify oskittcp of the abortion */
|
/* We have to notify oskittcp of the abortion */
|
||||||
DisType.Type = TDI_DISCONNECT_RELEASE;
|
TCPDisconnect
|
||||||
DisType.Context = Connection;
|
( Connection,
|
||||||
DisType.Irp = (PIRP)Bucket->Request.RequestContext;
|
TDI_DISCONNECT_RELEASE,
|
||||||
DisType.FileObject = IrpSp->FileObject;
|
NULL,
|
||||||
|
NULL,
|
||||||
|
Bucket->Request.RequestNotifyObject,
|
||||||
|
(PIRP)Bucket->Request.RequestContext );
|
||||||
|
|
||||||
ChewCreate(NULL, sizeof(DISCONNECT_TYPE),
|
Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
|
||||||
DispDoDisconnect, &DisType);
|
|
||||||
|
exFreePool(Bucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest,
|
while ((Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue