From 99fec75b6f182c23a1eb44f62392141356c6a6c5 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 2 Nov 2009 21:28:25 +0000 Subject: [PATCH 1/1] - Rework our oskittcp signalling - SignalledConnectionsList is now only used for connections that have pending requests - Remove another unused member from CONNECTION_ENDPOINT svn path=/trunk/; revision=43926 --- reactos/drivers/network/tcpip/include/tcp.h | 1 + .../drivers/network/tcpip/include/titypes.h | 1 - reactos/lib/drivers/ip/transport/tcp/event.c | 21 ++++++-- reactos/lib/drivers/ip/transport/tcp/tcp.c | 48 ++++++++++++++----- 4 files changed, 52 insertions(+), 19 deletions(-) diff --git a/reactos/drivers/network/tcpip/include/tcp.h b/reactos/drivers/network/tcpip/include/tcp.h index 5caa86e7637..e80d17f2500 100644 --- a/reactos/drivers/network/tcpip/include/tcp.h +++ b/reactos/drivers/network/tcpip/include/tcp.h @@ -105,6 +105,7 @@ NTSTATUS TCPAccept PVOID Context ); /* tcp.c */ +ULONG HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ); PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ); VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection ); diff --git a/reactos/drivers/network/tcpip/include/titypes.h b/reactos/drivers/network/tcpip/include/titypes.h index fa637d35ea8..eaac15a1496 100644 --- a/reactos/drivers/network/tcpip/include/titypes.h +++ b/reactos/drivers/network/tcpip/include/titypes.h @@ -309,7 +309,6 @@ typedef struct _CONNECTION_ENDPOINT { LIST_ENTRY SignalList; /* Entry in the list of sockets waiting for * notification service to the client */ UINT SignalState; /* Active signals from oskit */ - BOOLEAN Signalled; /* Are we a member of the signal list */ } CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT; diff --git a/reactos/lib/drivers/ip/transport/tcp/event.c b/reactos/lib/drivers/ip/transport/tcp/event.c index 0a13afff877..ee55ce9fd29 100644 --- a/reactos/lib/drivers/ip/transport/tcp/event.c +++ b/reactos/lib/drivers/ip/transport/tcp/event.c @@ -15,6 +15,8 @@ int TCPSocketState(void *ClientData, void *WhichConnection, OSK_UINT NewState ) { PCONNECTION_ENDPOINT Connection = WhichConnection; + ULONG OldState; + KIRQL OldIrql; ASSERT_LOCKED(&TCPLock); @@ -38,14 +40,23 @@ int TCPSocketState(void *ClientData, TI_DbgPrint(DEBUG_TCP,("Found socket %x\n", Connection)); } - TI_DbgPrint(MID_TRACE,("Connection signalled: %d\n", - Connection->Signalled)); + OldState = Connection->SignalState; Connection->SignalState |= NewState; - if( !Connection->Signalled ) { - Connection->Signalled = TRUE; - ExInterlockedInsertTailList( &SignalledConnectionsList, &Connection->SignalList, &SignalledConnectionsLock ); + + NewState = HandleSignalledConnection(Connection); + + KeAcquireSpinLock(&SignalledConnectionsLock, &OldIrql); + if ((NewState == 0 || NewState == SEL_FIN) && + (OldState != 0 && OldState != SEL_FIN)) + { + RemoveEntryList(&Connection->SignalList); + } + else if (NewState != 0 && NewState != SEL_FIN) + { + InsertTailList(&SignalledConnectionsList, &Connection->SignalList); } + KeReleaseSpinLock(&SignalledConnectionsLock, OldIrql); return 0; } diff --git a/reactos/lib/drivers/ip/transport/tcp/tcp.c b/reactos/lib/drivers/ip/transport/tcp/tcp.c index 5995ea4134f..1641718495b 100644 --- a/reactos/lib/drivers/ip/transport/tcp/tcp.c +++ b/reactos/lib/drivers/ip/transport/tcp/tcp.c @@ -22,7 +22,7 @@ FAST_MUTEX SleepingThreadsLock; RECURSIVE_MUTEX TCPLock; PORT_SET TCPPorts; -static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) { +ULONG HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) { NTSTATUS Status = STATUS_SUCCESS; PTCP_COMPLETION_ROUTINE Complete; PTDI_BUCKET Bucket; @@ -38,6 +38,7 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) { if( Connection->SignalState & SEL_FIN ) { TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n")); + Connection->SignalState &= ~SEL_READ; while ((Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest, &Connection->Lock )) != NULL) { @@ -49,6 +50,7 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) { exFreePool(Bucket); } + Connection->SignalState &= ~SEL_WRITE; while ((Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest, &Connection->Lock )) != NULL) { @@ -60,6 +62,7 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) { exFreePool(Bucket); } + Connection->SignalState &= ~SEL_ACCEPT; while ((Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest, &Connection->Lock )) != NULL) { @@ -75,6 +78,7 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) { exFreePool(Bucket); } + Connection->SignalState &= ~SEL_CONNECT; while ((Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest, &Connection->Lock )) != NULL) { @@ -85,12 +89,11 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) { exFreePool(Bucket); } - - Connection->SignalState = 0; } /* Things that can happen when we try the initial connection */ if( Connection->SignalState & SEL_CONNECT ) { + Connection->SignalState &= ~SEL_CONNECT; while( (Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest, &Connection->Lock )) != NULL ) { @@ -118,6 +121,7 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) { IsListEmpty(&Connection->ListenRequest) ? "empty" : "nonempty")); + Connection->SignalState &= ~SEL_ACCEPT; while( (Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest, &Connection->Lock )) != NULL ) { PIO_STACK_LOCATION IrpSp; @@ -137,6 +141,7 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) { TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n")); if( Status == STATUS_PENDING ) { + Connection->SignalState |= SEL_ACCEPT; ExInterlockedInsertHeadList( &Connection->ListenRequest, &Bucket->Entry, &Connection->Lock ); break; } else { @@ -152,6 +157,7 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) { IsListEmpty(&Connection->ReceiveRequest) ? "empty" : "nonempty")); + Connection->SignalState &= ~SEL_READ; while( (Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest, &Connection->Lock )) != NULL ) { OSK_UINT RecvLen = 0, Received = 0; @@ -197,6 +203,7 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) { } else if( Status == STATUS_PENDING ) { ExInterlockedInsertHeadList ( &Connection->ReceiveRequest, &Bucket->Entry, &Connection->Lock ); + Connection->SignalState |= SEL_READ; break; } else { TI_DbgPrint(DEBUG_TCP, @@ -212,6 +219,7 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) { IsListEmpty(&Connection->SendRequest) ? "empty" : "nonempty")); + Connection->SignalState &= ~SEL_WRITE; while( (Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest, &Connection->Lock )) != NULL ) { OSK_UINT SendLen = 0, Sent = 0; @@ -256,6 +264,7 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) { } else if( Status == STATUS_PENDING ) { ExInterlockedInsertHeadList ( &Connection->SendRequest, &Bucket->Entry, &Connection->Lock ); + Connection->SignalState |= SEL_WRITE; break; } else { TI_DbgPrint(DEBUG_TCP, @@ -267,20 +276,35 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) { } } - Connection->SignalState = 0; - Connection->Signalled = FALSE; + return Connection->SignalState; } -VOID DrainSignals() { +static VOID DrainSignals() { PCONNECTION_ENDPOINT Connection; - PLIST_ENTRY ListEntry; + PLIST_ENTRY CurrentEntry, NextEntry; + ULONG NewState; + KIRQL OldIrql; - while( (ListEntry = ExInterlockedRemoveHeadList(&SignalledConnectionsList, - &SignalledConnectionsLock)) != NULL) { - Connection = CONTAINING_RECORD( ListEntry, CONNECTION_ENDPOINT, + KeAcquireSpinLock(&SignalledConnectionsLock, &OldIrql); + CurrentEntry = SignalledConnectionsList.Flink; + while (CurrentEntry != &SignalledConnectionsList) + { + NextEntry = CurrentEntry->Flink; + Connection = CONTAINING_RECORD( CurrentEntry, CONNECTION_ENDPOINT, SignalList ); - HandleSignalledConnection( Connection ); + + KeReleaseSpinLock(&SignalledConnectionsLock, OldIrql); + NewState = HandleSignalledConnection(Connection); + KeAcquireSpinLock(&SignalledConnectionsLock, &OldIrql); + + if (NewState == SEL_FIN || NewState == 0) + { + RemoveEntryList(CurrentEntry); + } + + CurrentEntry = NextEntry; } + KeReleaseSpinLock(&SignalledConnectionsLock, OldIrql); } PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) { @@ -354,8 +378,6 @@ VOID TCPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket) IPPacket->TotalSize, IPPacket->HeaderSize ); - DrainSignals(); - TcpipRecursiveMutexLeave( &TCPLock ); } -- 2.17.1