[ros-diffs] [cmihail] 53092: [lwIP] - fix build because of missing rosip.h in sys_arch.c [TCPIP] - implement disconnect timer - minor code refactoring

cmihail at svn.reactos.org cmihail at svn.reactos.org
Fri Aug 5 21:33:20 UTC 2011


Author: cmihail
Date: Fri Aug  5 21:33:20 2011
New Revision: 53092

URL: http://svn.reactos.org/svn/reactos?rev=53092&view=rev
Log:
[lwIP]
- fix build because of missing rosip.h in sys_arch.c
[TCPIP]
- implement disconnect timer
- minor code refactoring

Modified:
    branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/include/tcp.h
    branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/tcpip/dispatch.c
    branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/event.c
    branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/tcp.c
    branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/sys_arch.c

Modified: branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/include/tcp.h
URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/include/tcp.h?rev=53092&r1=53091&r2=53092&view=diff
==============================================================================
--- branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/include/tcp.h [iso-8859-1] (original)
+++ branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/include/tcp.h [iso-8859-1] Fri Aug  5 21:33:20 2011
@@ -141,6 +141,7 @@
 NTSTATUS TCPDisconnect(
   PCONNECTION_ENDPOINT Connection,
   UINT Flags,
+  PLARGE_INTEGER Timeout,
   PTDI_CONNECTION_INFORMATION ConnInfo,
   PTDI_CONNECTION_INFORMATION ReturnInfo,
   PTCP_COMPLETION_ROUTINE Complete,
@@ -192,4 +193,21 @@
 TCPUpdateInterfaceIPInformation(PIP_INTERFACE IF);
 
 VOID
-FlushAllQueues(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status);
+FlushListenQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status);
+
+VOID
+FlushConnectQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status);
+
+VOID
+FlushReceiveQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN interlocked);
+
+VOID
+FlushSendQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN interlocked);
+
+VOID
+FlushShutdownQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN interlocked);
+
+VOID
+FlushAllQueues(PCONNECTION_ENDPOINT Connection, NTSTATUS Status);
+
+VOID CompleteBucket(PCONNECTION_ENDPOINT Connection, PTDI_BUCKET Bucket, const BOOLEAN Synchronous);

Modified: branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/tcpip/dispatch.c
URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/tcpip/dispatch.c?rev=53092&r1=53091&r2=53092&view=diff
==============================================================================
--- branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/tcpip/dispatch.c [iso-8859-1] (original)
+++ branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/tcpip/dispatch.c [iso-8859-1] Fri Aug  5 21:33:20 2011
@@ -518,7 +518,7 @@
   {
       Status = TCPDisconnect(TranContext->Handle.ConnectionContext,
                              DisReq->RequestFlags,
-                             //DisReq->RequestSpecific, /* FIXME */
+                             DisReq->RequestSpecific,
                              DisReq->RequestConnectionInformation,
                              DisReq->ReturnConnectionInformation,
                              DispDataRequestComplete,

Modified: branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/event.c
URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/event.c?rev=53092&r1=53091&r2=53092&view=diff
==============================================================================
--- branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/event.c [iso-8859-1] (original)
+++ branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/event.c [iso-8859-1] Fri Aug  5 21:33:20 2011
@@ -46,7 +46,6 @@
     ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
 }
 
-static
 VOID
 CompleteBucket(PCONNECTION_ENDPOINT Connection, PTDI_BUCKET Bucket, const BOOLEAN Synchronous)
 {
@@ -63,20 +62,138 @@
 }
 
 VOID
-FlushReceiveQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
-{
-    PTDI_BUCKET Bucket;
-    PLIST_ENTRY Entry;
-    
-    ReferenceObject(Connection);
-        
-    while ((Entry = ExInterlockedRemoveHeadList(&Connection->ReceiveRequest, &Connection->Lock)))
+FlushReceiveQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN interlocked)
+{
+    PTDI_BUCKET Bucket;
+    PLIST_ENTRY Entry;
+    
+    ReferenceObject(Connection);
+    
+    if (interlocked)
+    {
+        while ((Entry = ExInterlockedRemoveHeadList(&Connection->ReceiveRequest, &Connection->Lock)))
+        {
+            Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+        
+            TI_DbgPrint(DEBUG_TCP,
+                        ("Completing Receive request: %x %x\n",
+                         Bucket->Request, Status));
+        
+            Bucket->Status = Status;
+            Bucket->Information = 0;
+        
+            CompleteBucket(Connection, Bucket, FALSE);
+        }
+    }
+    else
+    {
+        while (!IsListEmpty(&Connection->ReceiveRequest))
+        {
+            Entry = RemoveHeadList(&Connection->ReceiveRequest);
+            
+            Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
+            
+            Bucket->Information = 0;
+            Bucket->Status = Status;
+            
+            CompleteBucket(Connection, Bucket, FALSE);
+        }
+    }
+
+    DereferenceObject(Connection);
+}
+
+VOID
+FlushSendQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN interlocked)
+{
+    PTDI_BUCKET Bucket;
+    PLIST_ENTRY Entry;
+    
+    ReferenceObject(Connection);
+
+    if (interlocked)
+    {
+        while ((Entry = ExInterlockedRemoveHeadList(&Connection->SendRequest, &Connection->Lock)))
+        {
+            Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );    
+        
+            TI_DbgPrint(DEBUG_TCP,
+                        ("Completing Send request: %x %x\n",
+                         Bucket->Request, Status));
+        
+            Bucket->Status = Status;
+            Bucket->Information = 0;
+        
+            CompleteBucket(Connection, Bucket, FALSE);
+        }
+    }
+    else
+    {
+        while (!IsListEmpty(&Connection->SendRequest))
+        {
+            Entry = RemoveHeadList(&Connection->SendRequest);
+            
+            Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
+            
+            Bucket->Information = 0;
+            Bucket->Status = Status;
+            
+            CompleteBucket(Connection, Bucket, FALSE);
+        }
+    }
+
+    DereferenceObject(Connection);
+}
+
+VOID
+FlushShutdownQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN interlocked)
+{
+    PTDI_BUCKET Bucket;
+    PLIST_ENTRY Entry;
+    
+    ReferenceObject(Connection);
+
+    if (interlocked)
+    {
+        while ((Entry = ExInterlockedRemoveHeadList(&Connection->ShutdownRequest, &Connection->Lock)))
+        {   
+            Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+        
+            Bucket->Status = Status;
+            Bucket->Information = 0;
+        
+            CompleteBucket(Connection, Bucket, FALSE);
+        }
+    }
+    else
+    {
+        while (!IsListEmpty(&Connection->ShutdownRequest))
+        {
+            Entry = RemoveHeadList(&Connection->ShutdownRequest);
+            
+            Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
+            
+            Bucket->Information = 0;
+            Bucket->Status = Status;
+            
+            CompleteBucket(Connection, Bucket, FALSE);
+        }
+    }
+
+    DereferenceObject(Connection);
+}
+
+VOID
+FlushConnectQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
+{
+    PTDI_BUCKET Bucket;
+    PLIST_ENTRY Entry;
+    
+    ReferenceObject(Connection);
+
+    while ((Entry = ExInterlockedRemoveHeadList(&Connection->ConnectRequest, &Connection->Lock)))
     {
         Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-        
-        TI_DbgPrint(DEBUG_TCP,
-                    ("Completing Receive request: %x %x\n",
-                     Bucket->Request, Status));
         
         Bucket->Status = Status;
         Bucket->Information = 0;
@@ -88,26 +205,37 @@
 }
 
 VOID
-FlushAllQueues(PCONNECTION_ENDPOINT Connection, NTSTATUS Status)
-{
-    PTDI_BUCKET Bucket;
-    PLIST_ENTRY Entry;
-    
-    ReferenceObject(Connection);
-        
-    while ((Entry = ExInterlockedRemoveHeadList(&Connection->ReceiveRequest, &Connection->Lock)))
+FlushListenQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
+{
+    PTDI_BUCKET Bucket;
+    PLIST_ENTRY Entry;
+    
+    ReferenceObject(Connection);
+
+    while ((Entry = ExInterlockedRemoveHeadList(&Connection->ListenRequest, &Connection->Lock)))
     {
         Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-        
-        TI_DbgPrint(DEBUG_TCP,
-                    ("Completing Receive request: %x %x\n",
-                     Bucket->Request, Status));
         
         Bucket->Status = Status;
         Bucket->Information = 0;
         
+        DereferenceObject(Bucket->AssociatedEndpoint);
         CompleteBucket(Connection, Bucket, FALSE);
     }
+
+    DereferenceObject(Connection);
+}
+
+VOID
+FlushAllQueues(PCONNECTION_ENDPOINT Connection, NTSTATUS Status)
+{
+    PTDI_BUCKET Bucket;
+    PLIST_ENTRY Entry;
+    
+    ReferenceObject(Connection);
+    
+    // flush receive queue
+    FlushReceiveQueue(Connection, Status, TRUE);
 
     /* We completed the reads successfully but we need to return failure now */
     if (Status == STATUS_SUCCESS)
@@ -115,40 +243,17 @@
         Status = STATUS_FILE_CLOSED;
     }
     
-    while ((Entry = ExInterlockedRemoveHeadList(&Connection->ListenRequest, &Connection->Lock)))
-    {
-        Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-        
-        Bucket->Status = Status;
-        Bucket->Information = 0;
-        
-        DereferenceObject(Bucket->AssociatedEndpoint);
-        CompleteBucket(Connection, Bucket, FALSE);
-    }
-    
-    while ((Entry = ExInterlockedRemoveHeadList(&Connection->SendRequest, &Connection->Lock)))
-    {
-        Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );    
-        
-        TI_DbgPrint(DEBUG_TCP,
-                    ("Completing Send request: %x %x\n",
-                     Bucket->Request, Status));
-        
-        Bucket->Status = Status;
-        Bucket->Information = 0;
-        
-        CompleteBucket(Connection, Bucket, FALSE);
-    }
-    
-    while ((Entry = ExInterlockedRemoveHeadList(&Connection->ConnectRequest, &Connection->Lock)))
-    {
-        Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-        
-        Bucket->Status = Status;
-        Bucket->Information = 0;
-        
-        CompleteBucket(Connection, Bucket, FALSE);
-    }
+    // flush listen queue
+    FlushListenQueue(Connection, Status);
+    
+    // flush send queue
+    FlushSendQueue(Connection, Status, TRUE);
+    
+    // flush connect queue
+    FlushConnectQueue(Connection, Status);
+
+    // flush shutdown queue
+    FlushShutdownQueue(Connection, Status, TRUE);
     
     DereferenceObject(Connection);
 }
@@ -166,7 +271,7 @@
     if (err == ERR_OK && Connection->SocketContext)
     {
         /* Just flush the receive queue and get out of here */
-        FlushReceiveQueue(Connection, STATUS_SUCCESS);
+        FlushReceiveQueue(Connection, STATUS_SUCCESS, TRUE);
     }
     else
     {
@@ -331,6 +436,18 @@
             CompleteBucket(Connection, Bucket, FALSE);
         }
     }
+
+    //  If we completed all outstanding send requests then finish all pending shutdown requests,
+    //  cancel the timer and dereference the connection
+    if (IsListEmpty(&Connection->SendRequest))
+    {
+        FlushShutdownQueue(Connection, STATUS_SUCCESS, FALSE);
+
+        if (KeCancelTimer(&Connection->DisconnectTimer))
+        {
+            DereferenceObject(Connection);
+        }
+    }
     
     DereferenceObject(Connection);
 }

Modified: branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/tcp.c
URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/tcp.c?rev=53092&r1=53091&r2=53092&view=diff
==============================================================================
--- branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/tcp.c [iso-8859-1] (original)
+++ branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/tcp.c [iso-8859-1] Fri Aug  5 21:33:20 2011
@@ -23,6 +23,51 @@
 
 #include "rosip.h"
 
+VOID NTAPI
+DisconnectTimeoutDpc(PKDPC Dpc,
+                     PVOID DeferredContext,
+                     PVOID SystemArgument1,
+                     PVOID SystemArgument2)
+{
+    PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)DeferredContext;
+    PLIST_ENTRY Entry;
+    PTDI_BUCKET Bucket;
+    NTSTATUS Status;
+    
+    LockObjectAtDpcLevel(Connection);
+    
+    /* We timed out waiting for pending sends so force it to shutdown */
+    Status = TCPTranslateError(LibTCPShutdown(Connection, 0, 1));
+    
+    while (!IsListEmpty(&Connection->SendRequest))
+    {
+        Entry = RemoveHeadList(&Connection->SendRequest);
+        
+        Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
+        
+        Bucket->Information = 0;
+        Bucket->Status = STATUS_FILE_CLOSED;
+        
+        CompleteBucket(Connection, Bucket, FALSE);
+    }
+    
+    while (!IsListEmpty(&Connection->ShutdownRequest))
+    {
+        Entry = RemoveHeadList( &Connection->ShutdownRequest );
+        
+        Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+        
+        Bucket->Status = STATUS_TIMEOUT;
+        Bucket->Information = 0;
+        
+        CompleteBucket(Connection, Bucket, FALSE);
+    }
+    
+    UnlockObjectFromDpcLevel(Connection);
+    
+    DereferenceObject(Connection);
+}
+
 VOID ConnectionFree(PVOID Object)
 {
     PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)Object;
@@ -57,6 +102,10 @@
     InitializeListHead(&Connection->SendRequest);
     InitializeListHead(&Connection->ShutdownRequest);
     InitializeListHead(&Connection->PacketQueue);
+
+    /* Initialize disconnect timer */
+    KeInitializeTimer(&Connection->DisconnectTimer);
+    KeInitializeDpc(&Connection->DisconnectDpc, DisconnectTimeoutDpc, Connection);
 
     /* Save client context pointer */
     Connection->ClientContext = ClientContext;
@@ -331,13 +380,16 @@
 NTSTATUS TCPDisconnect
 ( PCONNECTION_ENDPOINT Connection,
   UINT Flags,
+  PLARGE_INTEGER Timeout,
   PTDI_CONNECTION_INFORMATION ConnInfo,
   PTDI_CONNECTION_INFORMATION ReturnInfo,
   PTCP_COMPLETION_ROUTINE Complete,
   PVOID Context )
 {
     NTSTATUS Status = STATUS_INVALID_PARAMETER;
-    KIRQL OldIrql;
+    PTDI_BUCKET Bucket;
+    KIRQL OldIrql;
+    LARGE_INTEGER ActualTimeout;
 
     TI_DbgPrint(DEBUG_TCP,("[IP, TCPDisconnect] Called\n"));
 
@@ -347,11 +399,57 @@
     {
         if (Flags & TDI_DISCONNECT_RELEASE)
         {
-            Status = TCPTranslateError(LibTCPShutdown(Connection, 0, 1));
+            if (IsListEmpty(&Connection->SendRequest))
+            {
+                Status = TCPTranslateError(LibTCPShutdown(Connection, 0, 1));
+            }
+            else if (Timeout && Timeout->QuadPart == 0)
+            {
+                FlushSendQueue(Connection, STATUS_FILE_CLOSED, FALSE);
+                TCPTranslateError(LibTCPShutdown(Connection, 0, 1));
+                Status = STATUS_TIMEOUT;
+            }
+            else 
+            {
+                /* Use the timeout specified or 1 second if none was specified */
+                if (Timeout)
+                {
+                    ActualTimeout = *Timeout;
+                }
+                else
+                {
+                    ActualTimeout.QuadPart = -1000000;
+                }
+
+                /* We couldn't complete the request now because we need to wait for outstanding I/O */
+                Bucket = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG);
+                if (!Bucket)
+                {
+                    UnlockObject(Connection, OldIrql);
+                    return STATUS_NO_MEMORY;
+                }
+    
+                Bucket->Request.RequestNotifyObject = (PVOID)Complete;
+                Bucket->Request.RequestContext = Context;
+
+                InsertTailList(&Connection->ShutdownRequest, &Bucket->Entry);
+
+                ReferenceObject(Connection);
+                if (KeCancelTimer(&Connection->DisconnectTimer))
+                {
+                    DereferenceObject(Connection);
+                }
+                KeSetTimer(&Connection->DisconnectTimer, ActualTimeout, &Connection->DisconnectDpc);
+
+                Status = STATUS_PENDING;
+            }
         }
 
         if ((Flags & TDI_DISCONNECT_ABORT) || !Flags)
         {
+            FlushReceiveQueue(Connection, STATUS_FILE_CLOSED, FALSE);
+            FlushSendQueue(Connection, STATUS_FILE_CLOSED, FALSE);
+            FlushShutdownQueue(Connection, STATUS_FILE_CLOSED, FALSE);
             Status = TCPTranslateError(LibTCPShutdown(Connection, 1, 1));
         }
     }

Modified: branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/sys_arch.c
URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/sys_arch.c?rev=53092&r1=53091&r2=53092&view=diff
==============================================================================
--- branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/sys_arch.c [iso-8859-1] (original)
+++ branches/GSoC_2011/TcpIpDriver/lib/drivers/lwip/src/sys_arch.c [iso-8859-1] Fri Aug  5 21:33:20 2011
@@ -3,6 +3,8 @@
 #include "lwip/tcp.h"
 #include "lwip/pbuf.h"
 #include "lwip/err.h"
+
+#include "rosip.h"
 
 #include <debug.h>
 




More information about the Ros-diffs mailing list