Fix firefox exit. Implement a simple work queue for possibly dispatch level

callbacks for cancel and close.

svn path=/trunk/; revision=19943
This commit is contained in:
Art Yerkes
2005-12-07 08:50:27 +00:00
parent 8cc829e9de
commit f7fc8ee97d
8 changed files with 131 additions and 25 deletions
+12 -1
View File
@@ -521,6 +521,8 @@ VOID IPv4Receive(PIP_INTERFACE IF, PIP_PACKET IPPacket)
* IPPacket = Pointer to IP packet
*/
{
IP_ADDRESS Address;
TI_DbgPrint(DEBUG_IP, ("Received IPv4 datagram.\n"));
IPPacket->HeaderSize = (((PIPv4_HEADER)IPPacket->Header)->VerIHL & 0x0F) << 2;
@@ -562,7 +564,16 @@ VOID IPv4Receive(PIP_INTERFACE IF, PIP_PACKET IPPacket)
/* FIXME: Should we allow packets to be received on the wrong interface? */
/* XXX Find out if this packet is destined for us */
ProcessFragment(IF, IPPacket);
if( AddrLocateADEv4( IPPacket->DstAddr.Address.IPv4Address, &Address ) ) {
ProcessFragment( IF, IPPacket );
} else {
PNEIGHBOR_CACHE_ENTRY NCE;
if((NCE = RouteGetRouteToDestination( &IPPacket->DstAddr ))) {
IPSendDatagram( IPPacket, NCE, NULL, NULL );
}
}
#if 0
} else {
/* This packet is not destined for us. If we are a router,
@@ -647,4 +647,8 @@ NTSTATUS TCPGetPeerAddress
return STATUS_SUCCESS;
}
void TCPMarkForDisconnect( PCONNECTION_ENDPOINT Context, BOOLEAN Marked ) {
Context->Disconnecting = Marked;
}
/* EOF */
+13
View File
@@ -38,6 +38,9 @@ typedef struct TCPv4_HEADER {
#define TCPOPTLEN_MAX_SEG_SIZE 0x4
#define TCP_CANCEL_DISCONNECT 0
#define TCP_CANCEL_CLOSE 1
/* Data offset; 32-bit words (leftmost 4 bits); convert to bytes */
#define TCP_DATA_OFFSET(DataOffset)(((DataOffset) & 0xF0) >> (4-2))
@@ -57,6 +60,13 @@ typedef struct _SLEEPING_THREAD {
KEVENT Event;
} SLEEPING_THREAD, *PSLEEPING_THREAD;
typedef struct _CANCEL_REQUEST {
LIST_ENTRY Entry;
PVOID Context;
PIRP Irp;
UINT Flags, Type;
} CANCEL_REQUEST, *PCANCEL_REQUEST;
/* Retransmission timeout constants */
/* Lower bound for retransmission timeout in TCP timer ticks */
@@ -176,4 +186,7 @@ NTSTATUS TCPStartup(
NTSTATUS TCPShutdown(
VOID);
void TCPMarkForDisconnect(
PCONNECTION_ENDPOINT Connection, BOOLEAN Marked );
#endif /* __TCP_H */
@@ -188,6 +188,9 @@ extern LIST_ENTRY InterfaceListHead;
extern KSPIN_LOCK InterfaceListLock;
extern LIST_ENTRY AddressFileListHead;
extern KSPIN_LOCK AddressFileListLock;
extern LIST_ENTRY CancelQueue;
extern KSPIN_LOCK CancelQueueLock;
extern WORK_QUEUE_ITEM CancelQueueWork;
extern NDIS_HANDLE GlobalPacketPool;
extern NDIS_HANDLE GlobalBufferPool;
extern KSPIN_LOCK EntityListLock;
@@ -308,6 +308,8 @@ typedef struct _CONNECTION_ENDPOINT {
* notification service to the client */
UINT SignalState; /* Active signals from oskit */
BOOLEAN Signalled; /* Are we a member of the signal list */
BOOLEAN Disconnecting; /* Cancelling an irp .. we need to leave it
* alone for now */
} CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT;
+66 -16
View File
@@ -12,6 +12,8 @@
#include "precomp.h"
#include <pseh/pseh.h>
extern VOID DeleteConnectionEndpoint( PCONNECTION_ENDPOINT Endpoint );
NTSTATUS DispPrepareIrpForCancel(
PTRANSPORT_CONTEXT Context,
PIRP Irp,
@@ -135,6 +137,55 @@ VOID DispDataRequestComplete(
TI_DbgPrint(DEBUG_IRP, ("Done Completing IRP\n"));
}
VOID DDKAPI CancelQueuePassiveHandler( PVOID CancelRequestVoid )
{
KIRQL OldIrql;
PCANCEL_REQUEST CancelReq;
PLIST_ENTRY CqEntry;
KeAcquireSpinLock( &CancelQueueLock, &OldIrql );
TI_DbgPrint(DEBUG_IRP,("CANCEL QUEUE: Starting\n"));
for( CqEntry = CancelQueue.Flink;
CqEntry != &CancelQueue;
) {
CancelReq = CONTAINING_RECORD(CqEntry, CANCEL_REQUEST, Entry);
ExInterlockedRemoveHeadList( &CancelQueue, &CancelQueueLock );
CqEntry = CancelQueue.Flink;
KeReleaseSpinLock( &CancelQueueLock, OldIrql );
TI_DbgPrint(DEBUG_IRP,("CANCEL QUEUE: Executing %x\n", CancelReq));
switch( CancelReq->Type ) {
case TCP_CANCEL_DISCONNECT:
TCPDisconnect
( CancelReq->Context,
CancelReq->Flags,
NULL,
NULL,
DispDataRequestComplete,
CancelReq->Irp );
break;
case TCP_CANCEL_CLOSE:
TCPClose( CancelReq->Context );
DeleteConnectionEndpoint( CancelReq->Context );
break;
}
TCPMarkForDisconnect( CancelReq->Context, FALSE );
ExFreePool( CancelReq );
KeAcquireSpinLock( &CancelQueueLock, &OldIrql );
}
TI_DbgPrint(DEBUG_IRP,("CANCEL QUEUE: Ending\n"));
KeReleaseSpinLock( &CancelQueueLock, OldIrql );
}
VOID DDKAPI DispCancelRequest(
PDEVICE_OBJECT Device,
@@ -150,6 +201,7 @@ VOID DDKAPI DispCancelRequest(
PTRANSPORT_CONTEXT TranContext;
PFILE_OBJECT FileObject;
UCHAR MinorFunction;
PCANCEL_REQUEST CancelRequest;
/*NTSTATUS Status = STATUS_SUCCESS;*/
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
@@ -169,23 +221,21 @@ VOID DDKAPI DispCancelRequest(
/* Try canceling the request */
switch(MinorFunction) {
case TDI_SEND:
TCPDisconnect
( TranContext->Handle.ConnectionContext,
TDI_DISCONNECT_RELEASE,
NULL,
NULL,
DispDataRequestComplete,
Irp );
break;
case TDI_RECEIVE:
TCPDisconnect
( TranContext->Handle.ConnectionContext,
TDI_DISCONNECT_ABORT | TDI_DISCONNECT_RELEASE,
NULL,
NULL,
DispDataRequestComplete,
Irp );
CancelRequest = ExAllocatePoolWithTag
( sizeof(CANCEL_REQUEST), NonPagedPool, FOURCC('T','c','k','O') );
TCPMarkForDisconnect( TranContext->Handle.ConnectionContext, TRUE );
if( CancelRequest ) {
TI_DbgPrint(DEBUG_IRP,("CANCEL QUEUE:-> %x\n", CancelRequest));
CancelRequest->Flags = TDI_DISCONNECT_RELEASE |
(MinorFunction == TDI_RECEIVE) ? TDI_DISCONNECT_ABORT : 0;
CancelRequest->Context = TranContext->Handle.ConnectionContext;
CancelRequest->Irp = Irp;
CancelRequest->Type = TCP_CANCEL_DISCONNECT;
ExInterlockedInsertTailList
( &CancelQueue, &CancelRequest->Entry, &CancelQueueLock );
ExQueueWorkItem( &CancelQueueWork, CriticalWorkQueue );
}
break;
case TDI_SEND_DATAGRAM:
+19 -7
View File
@@ -10,7 +10,6 @@
#include "precomp.h"
/* List of all address file objects managed by this driver */
LIST_ENTRY AddressFileListHead;
KSPIN_LOCK AddressFileListLock;
@@ -352,6 +351,7 @@ NTSTATUS FileCloseAddress(
KIRQL OldIrql;
PADDRESS_FILE AddrFile;
NTSTATUS Status = STATUS_SUCCESS;
PCANCEL_REQUEST CancelReq;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
@@ -369,8 +369,16 @@ NTSTATUS FileCloseAddress(
switch (AddrFile->Protocol) {
case IPPROTO_TCP:
TCPFreePort( AddrFile->Port );
if( AddrFile->Listener )
TCPClose( AddrFile->Listener );
if( AddrFile->Listener ) {
CancelReq = ExAllocatePoolWithTag
( sizeof(CANCEL_REQUEST), NonPagedPool, FOURCC('T','c','l','s') );
if( CancelReq ) {
CancelReq->Type = TCP_CANCEL_CLOSE;
CancelReq->Context = AddrFile->Listener;
AddrFile->Listener = NULL;
ExQueueWorkItem( &CancelQueueWork, CriticalWorkQueue );
}
}
break;
case IPPROTO_UDP:
@@ -466,15 +474,19 @@ NTSTATUS FileCloseConnection(
{
PCONNECTION_ENDPOINT Connection;
NTSTATUS Status = STATUS_SUCCESS;
PCANCEL_REQUEST CancelReq;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
Connection = Request->Handle.ConnectionContext;
TcpipRecursiveMutexEnter( &TCPLock, TRUE );
TCPClose(Connection);
DeleteConnectionEndpoint(Connection);
TcpipRecursiveMutexLeave( &TCPLock );
CancelReq = ExAllocatePoolWithTag
( sizeof(CANCEL_REQUEST), NonPagedPool, FOURCC('T','c','l','s') );
if( CancelReq ) {
CancelReq->Type = TCP_CANCEL_CLOSE;
CancelReq->Context = Connection;
ExQueueWorkItem( &CancelQueueWork, CriticalWorkQueue );
}
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+12 -1
View File
@@ -14,7 +14,7 @@
#ifndef NDEBUG
DWORD DebugTraceLevel = DEBUG_ULTRA & ~(DEBUG_LOCK | DEBUG_PBUFFER);
#else
DWORD DebugTraceLevel = 0;
DWORD DebugTraceLevel = DEBUG_IRP;
#endif /* NDEBUG */
PDEVICE_OBJECT TCPDeviceObject = NULL;
@@ -35,6 +35,12 @@ KDPC IPTimeoutDpc;
KSPIN_LOCK IpWorkLock;
WORK_QUEUE_ITEM IpWorkItem;
/* Cancel Queue */
LIST_ENTRY CancelQueue;
KSPIN_LOCK CancelQueueLock;
WORK_QUEUE_ITEM CancelQueueWork;
extern VOID DDKAPI CancelQueuePassiveHandler( PVOID Context );
VOID TiWriteErrorLog(
PDRIVER_OBJECT DriverContext,
NTSTATUS ErrorCode,
@@ -809,6 +815,11 @@ DriverEntry(
InitializeListHead(&InterfaceListHead);
KeInitializeSpinLock(&InterfaceListLock);
/* Initialize cancellation queue */
InitializeListHead(&CancelQueue);
KeInitializeSpinLock(&CancelQueueLock);
ExInitializeWorkItem( &CancelQueueWork, CancelQueuePassiveHandler, NULL );
/* Initialize network level protocol subsystem */
IPStartup(RegistryPath);