- Rework our oskittcp signalling
authorCameron Gutman <aicommander@gmail.com>
Mon, 2 Nov 2009 21:28:25 +0000 (21:28 +0000)
committerCameron Gutman <aicommander@gmail.com>
Mon, 2 Nov 2009 21:28:25 +0000 (21:28 +0000)
 - 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
reactos/drivers/network/tcpip/include/titypes.h
reactos/lib/drivers/ip/transport/tcp/event.c
reactos/lib/drivers/ip/transport/tcp/tcp.c

index 5caa86e..e80d17f 100644 (file)
@@ -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 );
 
index fa637d3..eaac15a 100644 (file)
@@ -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;
 
 
index 0a13aff..ee55ce9 100644 (file)
@@ -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;
 }
index 5995ea4..1641718 100644 (file)
@@ -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 );
 }