Adapter = WorkItem->Adapter;
BytesTransferred = WorkItem->BytesTransferred;
+ exFreePool(WorkItem);
+
IPInitializePacket(&IPPacket, 0);
IPPacket.NdisPacket = Packet;
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;
+
+ WQItem->Packet = Packet;
+ WQItem->Adapter = Adapter;
+ WQItem->BytesTransferred = BytesTransferred;
- if( !ChewCreate
- ( NULL, sizeof(LAN_WQ_ITEM), LanReceiveWorker, &WQItem ) )
- ASSERT(0);
+ if (!ChewCreate( LanReceiveWorker, WQItem ))
+ exFreePool(WQItem);
}
VOID NTAPI ProtocolTransferDataComplete(
UINT Type;
PVOID Context;
PIRP Irp;
- PFILE_OBJECT FileObject;
} DISCONNECT_TYPE, *PDISCONNECT_TYPE;
NTSTATUS DispTdiAccept(
TI_DbgPrint(DEBUG_IRP, ("PostCancel: DoDisconnect done\n"));
DispDataRequestComplete(DisType->Irp, STATUS_CANCELLED, 0);
+
+ exFreePool(DisType);
}
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"));
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;
-
- TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp );
+ 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 );
+
+ if (!ChewCreate(DispDoDisconnect, DisType))
+ exFreePool(DisType);
+ }
IoReleaseCancelSpinLock(Irp->CancelIrql);
-
- if( !ChewCreate( &WorkItem, sizeof(DISCONNECT_TYPE),
- DispDoDisconnect, &DisType ) )
- ASSERT(0);
return;
case TDI_SEND_DATAGRAM:
*/
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*/
\r
#define NDEBUG\r
\r
-#define FOURCC(w,x,y,z) (((w) << 24) | ((x) << 16) | ((y) << 8) | (z))\r
+#define FOURCC(w,x,y,z) (((w) << 24) | ((x) << 16) | ((y) << 8) | (z))
+#define CHEW_TAG FOURCC('C','H','E','W')\r
\r
PDEVICE_OBJECT WorkQueueDevice;\r
LIST_ENTRY WorkQueue;\r
-KSPIN_LOCK WorkQueueLock;\r
+KSPIN_LOCK WorkQueueLock;
+KEVENT WorkQueueClear;\r
\r
typedef struct _WORK_ITEM {\r
LIST_ENTRY Entry;\r
PIO_WORKITEM WorkItem;\r
- VOID (*Worker)( PVOID Data );\r
- CHAR UserSpace[1];\r
+ VOID (*Worker)( PVOID WorkerContext );\r
+ PVOID WorkerContext;\r
} WORK_ITEM, *PWORK_ITEM;\r
\r
VOID ChewInit( PDEVICE_OBJECT DeviceObject ) {\r
WorkQueueDevice = DeviceObject;\r
InitializeListHead( &WorkQueue );\r
- KeInitializeSpinLock( &WorkQueueLock );\r
+ KeInitializeSpinLock( &WorkQueueLock );
+ KeInitializeEvent(&WorkQueueClear, NotificationEvent, TRUE);\r
}\r
\r
VOID ChewShutdown() {\r
- KIRQL OldIrql;\r
- PLIST_ENTRY Entry;\r
- PWORK_ITEM WorkItem;\r
-\r
- KeAcquireSpinLock( &WorkQueueLock, &OldIrql );\r
- \r
- while( !IsListEmpty( &WorkQueue ) ) {\r
- Entry = RemoveHeadList( &WorkQueue );\r
- WorkItem = CONTAINING_RECORD( Entry, WORK_ITEM, Entry );\r
- IoFreeWorkItem( WorkItem->WorkItem );\r
- ExFreePool( WorkItem );\r
- }\r
-\r
- KeReleaseSpinLock( &WorkQueueLock, OldIrql );\r
+ KeWaitForSingleObject(&WorkQueueClear, Executive, KernelMode, FALSE, NULL);\r
}\r
\r
VOID NTAPI ChewWorkItem( PDEVICE_OBJECT DeviceObject, PVOID ChewItem ) {\r
- PWORK_ITEM WorkItem = ChewItem;\r
-\r
- RemoveEntryList( &WorkItem->Entry );\r
+ PWORK_ITEM WorkItem = ChewItem;
+ KIRQL OldIrql;\r
\r
- if( WorkItem->Worker ) \r
- WorkItem->Worker( WorkItem->UserSpace );\r
+ WorkItem->Worker( WorkItem->WorkerContext );
\r
- IoFreeWorkItem( WorkItem->WorkItem );\r
- ExFreePool( WorkItem );\r
+ IoFreeWorkItem( WorkItem->WorkItem );
+
+ KeAcquireSpinLock(&WorkQueueLock, &OldIrql);
+ RemoveEntryList(&WorkItem->Entry);
+
+ if (IsListEmpty(&WorkQueue))
+ KeSetEvent(&WorkQueueClear, 0, FALSE);
+ KeReleaseSpinLock(&WorkQueueLock, OldIrql);
+
+ ExFreePoolWithTag(WorkItem, CHEW_TAG);\r
}\r
\r
BOOLEAN ChewCreate\r
-( PVOID *ItemPtr, SIZE_T Bytes, VOID (*Worker)( PVOID ), PVOID UserSpace ) {\r
- PWORK_ITEM Item;\r
- \r
- if( KeGetCurrentIrql() == PASSIVE_LEVEL ) {\r
- if( ItemPtr )\r
- *ItemPtr = NULL;\r
- Worker(UserSpace);\r
- return TRUE;\r
- } else {\r
- Item = ExAllocatePoolWithTag\r
+( VOID (*Worker)( PVOID ), PVOID WorkerContext ) {\r
+ PWORK_ITEM Item;
+\r Item = ExAllocatePoolWithTag\r
( NonPagedPool, \r
- sizeof( WORK_ITEM ) + Bytes - 1, \r
- FOURCC('C','H','E','W') );\r
+ sizeof( WORK_ITEM ), \r
+ CHEW_TAG );\r
\r
- if( Item ) {\r
- Item->WorkItem = IoAllocateWorkItem( WorkQueueDevice );\r
- if( !Item->WorkItem ) {\r
- ExFreePool( Item );\r
- return FALSE;\r
- }\r
- Item->Worker = Worker;\r
- if( Bytes && UserSpace )\r
- RtlCopyMemory( Item->UserSpace, UserSpace, Bytes );\r
- \r
- ExInterlockedInsertTailList\r
- ( &WorkQueue, &Item->Entry, &WorkQueueLock );\r
- IoQueueWorkItem\r
- ( Item->WorkItem, ChewWorkItem, DelayedWorkQueue, Item );\r
- \r
- if( ItemPtr ) \r
- *ItemPtr = Item;\r
-\r
- return TRUE;\r
- } else {\r
+ if( Item ) {\r
+ Item->WorkItem = IoAllocateWorkItem( WorkQueueDevice );\r
+ if( !Item->WorkItem ) {\r
+ ExFreePool( Item );\r
return FALSE;\r
}\r
- }\r
-}\r
+ Item->Worker = Worker;\r
+ Item->WorkerContext = WorkerContext;\r\r
+ ExInterlockedInsertTailList( &WorkQueue, &Item->Entry, &WorkQueueLock );
+ KeResetEvent(&WorkQueueClear);\r
+ IoQueueWorkItem( Item->WorkItem, ChewWorkItem, DelayedWorkQueue, Item );
\r
-VOID ChewRemove( PVOID Item ) {\r
- PWORK_ITEM WorkItem = Item;\r
- RemoveEntryList( &WorkItem->Entry );\r
- IoFreeWorkItem( WorkItem->WorkItem );\r
- ExFreePool( WorkItem );\r
+ return TRUE;\r
+ } else {\r
+ return FALSE;\r
+ }\r
}\r
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 );
+
+ Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
- ChewCreate(NULL, sizeof(DISCONNECT_TYPE),
- DispDoDisconnect, &DisType);
+ exFreePool(Bucket);
}
while ((Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest,