mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-30 04:13:33 +00:00
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:
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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"));
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user