[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