[ros-diffs] [cgutman] 52307: [IP] - Call the completion handler asynchronously to avoid a deadlock if AFD issues a synchronous request in its completion function - Complete all pending requests before closing ...

cgutman at svn.reactos.org cgutman at svn.reactos.org
Fri Jun 17 12:04:21 UTC 2011


Author: cgutman
Date: Fri Jun 17 12:04:20 2011
New Revision: 52307

URL: http://svn.reactos.org/svn/reactos?rev=52307&view=rev
Log:
[IP]
- Call the completion handler asynchronously to avoid a deadlock if AFD issues a synchronous request in its completion function
- Complete all pending requests before closing the socket
- Fixes send and receive on accepted sockets

Modified:
    branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/event.c
    branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/tcp.c

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=52307&r1=52306&r2=52307&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 Jun 17 12:04:20 2011
@@ -30,10 +30,41 @@
   "TIME_WAIT"   
 };
 
+static
+VOID
+BucketCompletionWorker(PVOID Context)
+{
+    PTDI_BUCKET Bucket = Context;
+    PTCP_COMPLETION_ROUTINE Complete;
+    
+    Complete = Bucket->Request.RequestNotifyObject;
+    
+    Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information);
+    
+    ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
+    
+    DereferenceObject(Bucket->AssociatedEndpoint);
+}
+
+static
+VOID
+CompleteBucket(PCONNECTION_ENDPOINT Connection, PTDI_BUCKET Bucket, BOOLEAN Synchronous)
+{
+    ReferenceObject(Connection);
+    Bucket->AssociatedEndpoint = Connection;
+    if (Synchronous)
+    {
+        BucketCompletionWorker(Bucket);
+    }
+    else
+    {
+        ChewCreate(BucketCompletionWorker, Bucket);
+    }
+}
+
 VOID
 FlushAllQueues(PCONNECTION_ENDPOINT Connection, NTSTATUS Status)
 {
-    PTCP_COMPLETION_ROUTINE Complete;
     PTDI_BUCKET Bucket;
     PLIST_ENTRY Entry;
     
@@ -52,11 +83,7 @@
         Bucket->Status = Status;
         Bucket->Information = 0;
         
-        Complete = Bucket->Request.RequestNotifyObject;
-        
-        Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information);
-        
-        ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
+        CompleteBucket(Connection, Bucket, TRUE);
     }
     
     if (Status == STATUS_SUCCESS)
@@ -69,11 +96,7 @@
         Bucket->Status = Status;
         Bucket->Information = 0;
         
-        Complete = Bucket->Request.RequestNotifyObject;
-        
-        Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information);
-        
-        ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
+        CompleteBucket(Connection, Bucket, TRUE);
     }
     
     while ((Entry = ExInterlockedRemoveHeadList(&Connection->SendRequest, &Connection->Lock)))
@@ -87,11 +110,7 @@
         Bucket->Status = Status;
         Bucket->Information = 0;
         
-        Complete = Bucket->Request.RequestNotifyObject;
-        
-        Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information);
-        
-        ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
+        CompleteBucket(Connection, Bucket, TRUE);
     }
     
     while ((Entry = ExInterlockedRemoveHeadList(&Connection->ConnectRequest, &Connection->Lock)))
@@ -101,11 +120,7 @@
         Bucket->Status = Status;
         Bucket->Information = 0;
         
-        Complete = Bucket->Request.RequestNotifyObject;
-        
-        Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information);
-        
-        ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
+        CompleteBucket(Connection, Bucket, TRUE);
     }
     
     DereferenceObject(Connection);
@@ -126,7 +141,6 @@
 TCPAcceptEventHandler(void *arg, struct tcp_pcb *newpcb)
 {
     PCONNECTION_ENDPOINT Connection = arg;
-    PTCP_COMPLETION_ROUTINE Complete;
     PTDI_BUCKET Bucket;
     PLIST_ENTRY Entry;
     PIRP Irp;
@@ -160,8 +174,6 @@
             Bucket->AssociatedEndpoint->SocketContext);
         
         DbgPrint("[IP, TCPAcceptEventHandler] Completing accept event %x\n", Status);
-        
-        Complete = Bucket->Request.RequestNotifyObject;
         
         if (Status == STATUS_SUCCESS)
         {
@@ -183,10 +195,7 @@
         
         DbgPrint("[IP, TCPAcceptEventHandler] Done!\n");
         
-        Complete(Bucket->Request.RequestContext,
-                    Bucket->Status, Bucket->Information);
-            
-        ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
+        CompleteBucket(Connection, Bucket, FALSE);
     }
     
     DereferenceObject(Connection);
@@ -196,7 +205,6 @@
 TCPSendEventHandler(void *arg, u16_t space)
 {
     PCONNECTION_ENDPOINT Connection = arg;
-    PTCP_COMPLETION_ROUTINE Complete;
     PTDI_BUCKET Bucket;
     PLIST_ENTRY Entry;
     PIRP Irp;
@@ -255,11 +263,7 @@
             
             DbgPrint("Completing send req %x\n", Status);
             
-            Complete = Bucket->Request.RequestNotifyObject;
-            
-            Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information);
-            
-            ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
+            CompleteBucket(Connection, Bucket, FALSE);
         }
     }
     
@@ -272,7 +276,6 @@
 TCPRecvEventHandler(void *arg, struct pbuf *p)
 {
     PCONNECTION_ENDPOINT Connection = arg;
-    PTCP_COMPLETION_ROUTINE Complete;
     PTDI_BUCKET Bucket;
     PLIST_ENTRY Entry;
     PIRP Irp;
@@ -324,11 +327,7 @@
         Bucket->Status = STATUS_SUCCESS;
         Bucket->Information = Received;
         
-        Complete = Bucket->Request.RequestNotifyObject;
-        
-        Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information);
-        
-        ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
+        CompleteBucket(Connection, Bucket, FALSE);
     }
 
     DereferenceObject(Connection);
@@ -342,7 +341,6 @@
 TCPConnectEventHandler(void *arg, err_t err)
 {
     PCONNECTION_ENDPOINT Connection = arg;
-    PTCP_COMPLETION_ROUTINE Complete;
     PTDI_BUCKET Bucket;
     PLIST_ENTRY Entry;
     
@@ -360,11 +358,7 @@
         
         DbgPrint("[IP, TCPConnectEventHandler] Completing connection request! (0x%x)\n", err);
         
-        Complete = Bucket->Request.RequestNotifyObject;
-        
-        Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information);
-        
-        ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
+        CompleteBucket(Connection, Bucket, FALSE);
     }
 
     DbgPrint("[IP, TCPConnectEventHandler] Done\n");

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=52307&r1=52306&r2=52307&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 Jun 17 12:04:20 2011
@@ -349,9 +349,9 @@
     /* Don't try to close again if the other side closed us already */
     if (Socket)
     {
+        FlushAllQueues(Connection, STATUS_CANCELLED);
+
         LibTCPClose(Socket);
-        
-        FlushAllQueues(Connection, STATUS_CANCELLED);
     }
 
     UnlockObject(Connection, OldIrql);




More information about the Ros-diffs mailing list