[TCPIP][IP] Use an ERESOURCE as mutex for address files & connection end points
[reactos.git] / sdk / lib / drivers / ip / transport / tcp / event.c
index 02613c2..9294815 100644 (file)
@@ -50,125 +50,66 @@ CompleteBucket(PCONNECTION_ENDPOINT Connection, PTDI_BUCKET Bucket, const BOOLEA
 }
 
 VOID
-FlushReceiveQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN interlocked)
+FlushReceiveQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
 {
     PTDI_BUCKET Bucket;
     PLIST_ENTRY Entry;
 
-    ReferenceObject(Connection);
+    ASSERT_TCPIP_OBJECT_LOCKED(Connection);
 
-    if (interlocked)
+    while (!IsListEmpty(&Connection->ReceiveRequest))
     {
-        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));
+        Entry = RemoveHeadList(&Connection->ReceiveRequest);
 
-            Bucket->Status = Status;
-            Bucket->Information = 0;
+        Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
 
-            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;
+        Bucket->Information = 0;
+        Bucket->Status = Status;
 
-            CompleteBucket(Connection, Bucket, FALSE);
-        }
+        CompleteBucket(Connection, Bucket, FALSE);
     }
-
-    DereferenceObject(Connection);
 }
 
 VOID
-FlushSendQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN interlocked)
+FlushSendQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
 {
     PTDI_BUCKET Bucket;
     PLIST_ENTRY Entry;
 
-    ReferenceObject(Connection);
+    ASSERT_TCPIP_OBJECT_LOCKED(Connection);
 
-    if (interlocked)
+    while (!IsListEmpty(&Connection->SendRequest))
     {
-        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);
+        Entry = RemoveHeadList(&Connection->SendRequest);
 
-            Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
+        Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
 
-            Bucket->Information = 0;
-            Bucket->Status = Status;
+        Bucket->Information = 0;
+        Bucket->Status = Status;
 
-            CompleteBucket(Connection, Bucket, FALSE);
-        }
+        CompleteBucket(Connection, Bucket, FALSE);
     }
-
-    DereferenceObject(Connection);
 }
 
 VOID
-FlushShutdownQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status, const BOOLEAN interlocked)
+FlushShutdownQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
 {
     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;
+    ASSERT_TCPIP_OBJECT_LOCKED(Connection);
 
-            CompleteBucket(Connection, Bucket, FALSE);
-        }
-    }
-    else
+    while (!IsListEmpty(&Connection->ShutdownRequest))
     {
-        while (!IsListEmpty(&Connection->ShutdownRequest))
-        {
-            Entry = RemoveHeadList(&Connection->ShutdownRequest);
+        Entry = RemoveHeadList(&Connection->ShutdownRequest);
 
-            Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
+        Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
 
-            Bucket->Information = 0;
-            Bucket->Status = Status;
+        Bucket->Information = 0;
+        Bucket->Status = Status;
 
-            CompleteBucket(Connection, Bucket, FALSE);
-        }
+        CompleteBucket(Connection, Bucket, FALSE);
     }
-
-    DereferenceObject(Connection);
 }
 
 VOID
@@ -177,10 +118,11 @@ FlushConnectQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
     PTDI_BUCKET Bucket;
     PLIST_ENTRY Entry;
 
-    ReferenceObject(Connection);
+    ASSERT_TCPIP_OBJECT_LOCKED(Connection);
 
-    while ((Entry = ExInterlockedRemoveHeadList(&Connection->ConnectRequest, &Connection->Lock)))
+    while (!IsListEmpty(&Connection->ConnectRequest))
     {
+        Entry = RemoveHeadList(&Connection->ConnectRequest);
         Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
 
         Bucket->Status = Status;
@@ -188,8 +130,6 @@ FlushConnectQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
 
         CompleteBucket(Connection, Bucket, FALSE);
     }
-
-    DereferenceObject(Connection);
 }
 
 VOID
@@ -198,10 +138,11 @@ FlushListenQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
     PTDI_BUCKET Bucket;
     PLIST_ENTRY Entry;
 
-    ReferenceObject(Connection);
+    ASSERT_TCPIP_OBJECT_LOCKED(Connection);
 
-    while ((Entry = ExInterlockedRemoveHeadList(&Connection->ListenRequest, &Connection->Lock)))
+    while (!IsListEmpty(&Connection->ListenRequest))
     {
+        Entry = RemoveHeadList(&Connection->ListenRequest);
         Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
 
         Bucket->Status = Status;
@@ -210,17 +151,13 @@ FlushListenQueue(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
         DereferenceObject(Bucket->AssociatedEndpoint);
         CompleteBucket(Connection, Bucket, FALSE);
     }
-
-    DereferenceObject(Connection);
 }
 
 VOID
 FlushAllQueues(PCONNECTION_ENDPOINT Connection, NTSTATUS Status)
 {
-    ReferenceObject(Connection);
-
     // flush receive queue
-    FlushReceiveQueue(Connection, Status, TRUE);
+    FlushReceiveQueue(Connection, Status);
 
     /* We completed the reads successfully but we need to return failure now */
     if (Status == STATUS_SUCCESS)
@@ -232,15 +169,13 @@ FlushAllQueues(PCONNECTION_ENDPOINT Connection, NTSTATUS Status)
     FlushListenQueue(Connection, Status);
 
     // flush send queue
-    FlushSendQueue(Connection, Status, TRUE);
+    FlushSendQueue(Connection, Status);
 
     // flush connect queue
     FlushConnectQueue(Connection, Status);
 
     // flush shutdown queue
-    FlushShutdownQueue(Connection, Status, TRUE);
-
-    DereferenceObject(Connection);
+    FlushShutdownQueue(Connection, Status);
 }
 
 VOID
@@ -248,18 +183,17 @@ TCPFinEventHandler(void *arg, const err_t err)
 {
    PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)arg, LastConnection;
    const NTSTATUS Status = TCPTranslateError(err);
-   KIRQL OldIrql;
 
    ASSERT(Connection->SocketContext == NULL);
    ASSERT(Connection->AddressFile);
    ASSERT(err != ERR_OK);
 
+   LockObject(Connection);
+
    /* Complete all outstanding requests now */
    FlushAllQueues(Connection, Status);
 
-   LockObject(Connection, &OldIrql);
-
-   LockObjectAtDpcLevel(Connection->AddressFile);
+   LockObject(Connection->AddressFile);
 
    /* Unlink this connection from the address file */
    if (Connection->AddressFile->Connection == Connection)
@@ -284,13 +218,13 @@ TCPFinEventHandler(void *arg, const err_t err)
        }
    }
 
-   UnlockObjectFromDpcLevel(Connection->AddressFile);
+   UnlockObject(Connection->AddressFile);
 
    /* Remove the address file from this connection */
    DereferenceObject(Connection->AddressFile);
    Connection->AddressFile = NULL;
 
-   UnlockObject(Connection, OldIrql);
+   UnlockObject(Connection);
 }
 
 VOID
@@ -301,14 +235,15 @@ TCPAcceptEventHandler(void *arg, PTCP_PCB newpcb)
     PLIST_ENTRY Entry;
     PIRP Irp;
     NTSTATUS Status;
-    KIRQL OldIrql;
 
-    ReferenceObject(Connection);
+    LockObject(Connection);
 
-    while ((Entry = ExInterlockedRemoveHeadList(&Connection->ListenRequest, &Connection->Lock)))
+    while (!IsListEmpty(&Connection->ListenRequest))
     {
         PIO_STACK_LOCATION IrpSp;
 
+        Entry = RemoveHeadList(&Connection->ListenRequest);
+
         Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
 
         Irp = Bucket->Request.RequestContext;
@@ -326,7 +261,7 @@ TCPAcceptEventHandler(void *arg, PTCP_PCB newpcb)
 
         if (Status == STATUS_SUCCESS)
         {
-            LockObject(Bucket->AssociatedEndpoint, &OldIrql);
+            LockObject(Bucket->AssociatedEndpoint);
 
             /* sanity assert...this should never be in anything else but a CLOSED state */
             ASSERT( ((PTCP_PCB)Bucket->AssociatedEndpoint->SocketContext)->state == CLOSED );
@@ -337,9 +272,9 @@ TCPAcceptEventHandler(void *arg, PTCP_PCB newpcb)
             /* free previously created socket context (we don't use it, we use newpcb) */
             Bucket->AssociatedEndpoint->SocketContext = newpcb;
 
-            LibTCPAccept(newpcb, (PTCP_PCB)Connection->SocketContext, Bucket->AssociatedEndpoint);
+            UnlockObject(Bucket->AssociatedEndpoint);
 
-            UnlockObject(Bucket->AssociatedEndpoint, OldIrql);
+            LibTCPAccept(newpcb, (PTCP_PCB)Connection->SocketContext, Bucket->AssociatedEndpoint);
         }
 
         DereferenceObject(Bucket->AssociatedEndpoint);
@@ -352,7 +287,7 @@ TCPAcceptEventHandler(void *arg, PTCP_PCB newpcb)
         }
     }
 
-    DereferenceObject(Connection);
+    UnlockObject(Connection);
 }
 
 VOID
@@ -367,12 +302,17 @@ TCPSendEventHandler(void *arg, const u16_t space)
     ULONG BytesSent;
 
     ReferenceObject(Connection);
+    LockObject(Connection);
 
-    while ((Entry = ExInterlockedRemoveHeadList(&Connection->SendRequest, &Connection->Lock)))
+    while (!IsListEmpty(&Connection->SendRequest))
     {
         UINT SendLen = 0;
         PVOID SendBuffer = 0;
 
+        Entry = RemoveHeadList(&Connection->SendRequest);
+
+        UnlockObject(Connection);
+
         Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
 
         Irp = Bucket->Request.RequestContext;
@@ -400,9 +340,8 @@ TCPSendEventHandler(void *arg, const u16_t space)
 
         if( Status == STATUS_PENDING )
         {
-            ExInterlockedInsertHeadList(&Connection->SendRequest,
-                                        &Bucket->Entry,
-                                        &Connection->Lock);
+            LockObject(Connection);
+            InsertHeadList(&Connection->SendRequest, &Bucket->Entry);
             break;
         }
         else
@@ -416,13 +355,15 @@ TCPSendEventHandler(void *arg, const u16_t space)
 
             CompleteBucket(Connection, Bucket, FALSE);
         }
+
+        LockObject(Connection);
     }
 
     //  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);
+        FlushShutdownQueue(Connection, STATUS_SUCCESS);
 
         if (KeCancelTimer(&Connection->DisconnectTimer))
         {
@@ -430,6 +371,8 @@ TCPSendEventHandler(void *arg, const u16_t space)
         }
     }
 
+    UnlockObject(Connection);
+
     DereferenceObject(Connection);
 }
 
@@ -446,10 +389,11 @@ TCPRecvEventHandler(void *arg)
     PUCHAR RecvBuffer;
     NTSTATUS Status;
 
-    ReferenceObject(Connection);
+    LockObject(Connection);
 
-    while ((Entry = ExInterlockedRemoveHeadList(&Connection->ReceiveRequest, &Connection->Lock)))
+    while(!IsListEmpty(&Connection->ReceiveRequest))
     {
+        Entry = RemoveHeadList(&Connection->ReceiveRequest);
         Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
 
         Irp = Bucket->Request.RequestContext;
@@ -460,9 +404,7 @@ TCPRecvEventHandler(void *arg)
         Status = LibTCPGetDataFromConnectionQueue(Connection, RecvBuffer, RecvLen, &Received);
         if (Status == STATUS_PENDING)
         {
-            ExInterlockedInsertHeadList(&Connection->ReceiveRequest,
-                                        &Bucket->Entry,
-                                        &Connection->Lock);
+            InsertHeadList(&Connection->ReceiveRequest, &Bucket->Entry);
             break;
         }
 
@@ -471,8 +413,7 @@ TCPRecvEventHandler(void *arg)
 
         CompleteBucket(Connection, Bucket, FALSE);
     }
-
-    DereferenceObject(Connection);
+    UnlockObject(Connection);
 }
 
 VOID
@@ -482,10 +423,11 @@ TCPConnectEventHandler(void *arg, const err_t err)
     PTDI_BUCKET Bucket;
     PLIST_ENTRY Entry;
 
-    ReferenceObject(Connection);
+    LockObject(Connection);
 
-    while ((Entry = ExInterlockedRemoveHeadList(&Connection->ConnectRequest, &Connection->Lock)))
+    while (!IsListEmpty(&Connection->ConnectRequest))
     {
+        Entry = RemoveHeadList(&Connection->ConnectRequest);
 
         Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
 
@@ -495,5 +437,5 @@ TCPConnectEventHandler(void *arg, const err_t err)
         CompleteBucket(Connection, Bucket, FALSE);
     }
 
-    DereferenceObject(Connection);
+    UnlockObject(Connection);
 }