Author: zhu
Date: Wed Jul  6 20:53:31 2016
New Revision: 71835

URL: http://svn.reactos.org/svn/reactos?rev=71835&view=rev
Log:
Mostly cleanup. Removed abusive use of cancel spin lock, thanks to David for 
pointing that out for me. 

Modified:
    branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c
    branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c

Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c?rev=71835&r1=71834&r2=71835&view=diff
==============================================================================
--- branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c       
[iso-8859-1] (original)
+++ branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c       
[iso-8859-1] Wed Jul  6 20:53:31 2016
@@ -9,6 +9,8 @@
 
 #define NDEBUG
 #include <debug.h>
+
+volatile long int PcbCount;
 
 typedef struct
 {
@@ -22,6 +24,7 @@
 
 /* The pool tags we will use for all of our allocation */
 #define TAG_ADDRESS_FILE 'FrdA'
+#define TAG_DGRAM_REQST  'DgRq'
 #define TAG_TCP_CONTEXT  'TCPx'
 #define TAG_TCP_REQUEST  'TCPr'
 
@@ -42,10 +45,9 @@
        PTCP_CONTEXT Context;
        PTCP_REQUEST Request;
        KIRQL OldIrql;
+       NTSTATUS Status;
        
        DPRINT1("Prepare for cancel\n");
-       
-       IoAcquireCancelSpinLock(&OldIrql);
        
        if (!Irp->Cancel)
        {
@@ -53,9 +55,8 @@
                if (!Request)
                {
                        DPRINT1("Allocation failed, out of memory\n");
-                       IoReleaseCancelSpinLock(OldIrql);
-                       
-                       return STATUS_NO_MEMORY;
+                       Status = STATUS_NO_MEMORY;
+                       goto RETURN;
                }
                
                IrpSp = IoGetCurrentIrpStackLocation(Irp);
@@ -66,31 +67,28 @@
                Request->CancelMode = CancelMode;
                Request->PendingMode = PendingMode;
                
-               KeAcquireSpinLockAtDpcLevel(&Context->RequestListLock);
+               KeAcquireSpinLock(&Context->RequestListLock, &OldIrql);
+               IoSetCancelRoutine(Irp, CancelRoutine);
                InsertTailList(&Context->RequestListHead, &Request->ListEntry);
-               KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock);
+               KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
                
-               IoSetCancelRoutine(Irp, CancelRoutine);
+               Status = STATUS_SUCCESS;
+               DPRINT1("Prepared for cancel\n");
                
-               IoReleaseCancelSpinLock(OldIrql);
-               
-               DPRINT1("Prepared for cancel\n");
-
-               return STATUS_SUCCESS;
+               goto RETURN;
        }
        
        DPRINT1("Already cancelled\n");
-       
-       IoReleaseCancelSpinLock(OldIrql);
        
        Irp->IoStatus.Status = STATUS_CANCELLED;
        Irp->IoStatus.Information = 0;
        
-       return STATUS_CANCELLED;
+RETURN:
+       return Status;
 }
 
 /* implementation in testing */
-/* Does not dequeue the request, simply marks it as cancelled */
+/* TODO: get rid of datagram support, or merge datagram stuff into here */
 VOID
 NTAPI
 CancelRequestRoutine(
@@ -123,10 +121,11 @@
        }
        
 TCP_CANCEL:
+       KeAcquireSpinLock(&Context->RequestListLock, &OldIrql);
+       
        Irp->IoStatus.Status = STATUS_CANCELLED;
        Irp->IoStatus.Information = 0;
-       
-       KeAcquireSpinLock(&Context->RequestListLock, &OldIrql);
+       IoSetCancelRoutine(Irp, NULL);
        
        AddressFile = Context->AddressFile;
        DPRINT1("AddressFile at %08x\n", AddressFile);
@@ -145,6 +144,8 @@
                                                AddressFile->lwip_tcp_pcb = 
NULL;
                                        }
                                        tcp_abort(Context->lwip_tcp_pcb);
+                                       InterlockedDecrement(&PcbCount);
+                                       DPRINT1("\n    PCB Count: %d\n", 
PcbCount);
                                        Context->lwip_tcp_pcb = NULL;
                                        
                                        RemoveEntryList(Entry);
@@ -162,6 +163,8 @@
                                                AddressFile->lwip_tcp_pcb = 
NULL;
                                        }
                                        tcp_close(Context->lwip_tcp_pcb);
+                                       InterlockedDecrement(&PcbCount);
+                                       DPRINT1("\n    PCB Count: %d\n", 
PcbCount);
                                        Context->lwip_tcp_pcb = NULL;
                                        
                                        RemoveEntryList(Entry);
@@ -194,15 +197,9 @@
        DPRINT1("DGRAM_CANCEL\n");
        
 FINISH:
-       DPRINT1("\n Minor Function: %08x\n", IrpSp->MinorFunction);
-
-       IoAcquireCancelSpinLock(&OldIrql);
-       IoSetCancelRoutine(Irp, NULL);
-       IoReleaseCancelSpinLock(OldIrql);
-       
        IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
        
-       DPRINT1("\n  CancelRequestRoutine Exiting\n");
+       DPRINT1("CancelRequestRoutine Exiting\n");
        
        return;
 }
@@ -212,6 +209,8 @@
 {
     KeInitializeSpinLock(&AddressListLock);
     InitializeListHead(&AddressListHead);
+       
+       PcbCount = 0;
 }
 
 static
@@ -238,7 +237,6 @@
        PLIST_ENTRY Temp;
        PIRP Irp;
        KIRQL OldIrql;
-       KIRQL CancelIrql;
        
        NTSTATUS Status;
        
@@ -293,10 +291,8 @@
                                        {
                                                if (Irp->Cancel)
                                                {
-                                                       
IoAcquireCancelSpinLock(&CancelIrql);
                                                        Irp->Cancel = FALSE;
                                                        IoSetCancelRoutine(Irp, 
NULL);
-                                                       
IoReleaseCancelSpinLock(CancelIrql);
                                                }
                                                Irp->IoStatus.Status = Status;
                                                Irp->IoStatus.Information = 0;
@@ -312,22 +308,24 @@
                                
                                if (Context->lwip_tcp_pcb != 
AddressFile->lwip_tcp_pcb)
                                {
-                                       tcp_close(Context->lwip_tcp_pcb);
+                                       tcp_abort(Context->lwip_tcp_pcb);
+                                       InterlockedDecrement(&PcbCount);
+                                       DPRINT1("\n    PCB Count\n", PcbCount);
                                }
                                Context->lwip_tcp_pcb = NULL;
                                
                                Entry = Entry->Flink;
                        }
                        
+                       AddressFile->lwip_tcp_pcb = NULL;
+                       
                        KeReleaseSpinLock(&AddressFile->ContextListLock, 
OldIrql);
-                       
-                       AddressFile->lwip_tcp_pcb = NULL;
                        
                        return;
                case TDI_CONNECTION_FILE :
                        Context = (PTCP_CONTEXT)arg;
                        DPRINT1("AddressFile at %08x\n", Context->AddressFile);
-                       KeAcquireSpinLockAtDpcLevel(&Context->RequestListLock);
+                       KeAcquireSpinLock(&Context->RequestListLock, &OldIrql);
                                
                        HeadNest = &Context->RequestListHead;
                        EntryNest = HeadNest->Flink;
@@ -339,10 +337,8 @@
                                {
                                        if (Irp->Cancel)
                                        {
-                                               
IoAcquireCancelSpinLock(&CancelIrql);
                                                Irp->Cancel = FALSE;
                                                IoSetCancelRoutine(Irp, NULL);
-                                               
IoReleaseCancelSpinLock(CancelIrql);
                                        }
                                        Irp->IoStatus.Status = Status;
                                        Irp->IoStatus.Information = 0;
@@ -354,9 +350,10 @@
                                EntryNest = Temp;
                        }
                        
-                       
KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock);
+                       KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
                        
-                       if (Context->lwip_tcp_pcb == 
Context->AddressFile->lwip_tcp_pcb);
+                       if (Context->AddressFile && 
+                               (Context->lwip_tcp_pcb == 
Context->AddressFile->lwip_tcp_pcb))
                        {
                                Context->AddressFile->lwip_tcp_pcb = NULL;
                        }
@@ -388,8 +385,7 @@
     DPRINT1("Receiving datagram for addr 0x%08x on port %u.\n", 
ip4_addr_get_u32(addr), port);
 
     /* Block any cancellation that could occur */
-    IoAcquireCancelSpinLock(&OldIrql);
-    KeAcquireSpinLockAtDpcLevel(&AddressFile->RequestLock);
+    KeAcquireSpinLock(&AddressFile->RequestLock, &OldIrql);
 
     ListEntry = AddressFile->RequestListHead.Flink;
     while (ListEntry != &AddressFile->RequestListHead)
@@ -415,8 +411,7 @@
             RemoveEntryList(&Request->ListEntry);
             Result = TRUE;
 
-            KeReleaseSpinLockFromDpcLevel(&AddressFile->RequestLock);
-            IoReleaseCancelSpinLock(OldIrql);
+            KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql);
 
             /* In case of UDP, lwip provides a pbuf directly pointing to the 
data.
              * In other case, we must skip the IP header */
@@ -439,16 +434,14 @@
                 Irp->IoStatus.Status = STATUS_SUCCESS;
             IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
 
-            ExFreePoolWithTag(Request, TAG_TCP_REQUEST);
+            ExFreePoolWithTag(Request, TAG_DGRAM_REQST);
 
             /* Start again from the beginning */
-            IoAcquireCancelSpinLock(&OldIrql);
-            KeAcquireSpinLockAtDpcLevel(&AddressFile->RequestLock);
+            KeAcquireSpinLock(&AddressFile->RequestLock, &OldIrql);
         }
     }
 
-    KeReleaseSpinLockFromDpcLevel(&AddressFile->RequestLock);
-    IoReleaseCancelSpinLock(OldIrql);
+    KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql);
 
     return Result;
 }
@@ -488,9 +481,8 @@
        
        DPRINT1("lwIP TCP Accept Callback\n");
        
-       IoAcquireCancelSpinLock(&OldIrql);
        AddressFile = (PADDRESS_FILE)arg;
-       KeAcquireSpinLockAtDpcLevel(&AddressFile->ContextListLock);
+       KeAcquireSpinLock(&AddressFile->ContextListLock, &OldIrql);
        
        Head = &AddressFile->ContextListHead;
        Entry = Head->Flink;
@@ -499,10 +491,12 @@
                Context = CONTAINING_RECORD(Entry, TCP_CONTEXT, ListEntry);
                if (Context->TcpState == TCP_STATE_LISTENING)
                {
-                       
KeReleaseSpinLockFromDpcLevel(&AddressFile->ContextListLock);
-                       KeAcquireSpinLockAtDpcLevel(&Context->RequestListLock);
+                       KeReleaseSpinLock(&AddressFile->ContextListLock, 
OldIrql);
+                       KeAcquireSpinLock(&Context->RequestListLock, &OldIrql);
                        
                        Context->lwip_tcp_pcb = newpcb;
+                       InterlockedIncrement(&PcbCount);
+                       DPRINT1("\n    PCB Count: %d\n", PcbCount);
                        Context->TcpState = TCP_STATE_ACCEPTED;
                        tcp_accepted(AddressFile->lwip_tcp_pcb);
                        Head = &Context->RequestListHead;
@@ -513,10 +507,11 @@
                        IrpSp = IoGetCurrentIrpStackLocation(Irp);
                        if (!Irp || IrpSp->MinorFunction != TDI_LISTEN)
                        {
-                               DPRINT1("Received callback for canceld 
TDI_LISTEN\n");
+                               DPRINT1("Received accept callback for cancelled 
TDI_LISTEN\n");
                                RemoveEntryList(Entry);
                                Entry = Entry->Flink;
                                ExFreePoolWithTag(Request, TAG_TCP_REQUEST);
+                               KeReleaseSpinLock(&Context->RequestListLock, 
OldIrql);
                                return ERR_ABRT;
                        }
                        
@@ -525,19 +520,17 @@
                        IoSetCancelRoutine(Irp, NULL);
                        Irp->Cancel = FALSE;
                        
-                       IoReleaseCancelSpinLock(OldIrql);
+                       KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
                        
                        Irp->IoStatus.Status = STATUS_SUCCESS;
                        IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
-                       
                        return ERR_OK;
                }
                Entry = Entry->Flink;
        }
        
-       KeReleaseSpinLockFromDpcLevel(&AddressFile->ContextListLock);
-       IoReleaseCancelSpinLock(OldIrql);
-       
+       KeReleaseSpinLock(&AddressFile->ContextListLock, OldIrql);
+       DPRINT1("Did not find a valid TDI_LISTEN\n");
        return ERR_ABRT;
 }
 
@@ -568,8 +561,7 @@
        DPRINT1("lwIP TCP Sent Callback\n");
        
        Context = (PTCP_CONTEXT)arg;
-       IoAcquireCancelSpinLock(&OldIrql);
-       KeAcquireSpinLockAtDpcLevel(&Context->RequestListLock);
+       KeAcquireSpinLock(&Context->RequestListLock, &OldIrql);
        
        Head = &Context->RequestListHead;
        Entry = Head->Flink;
@@ -584,18 +576,18 @@
                }
                Entry = Entry->Flink;
        }
+       
        DPRINT1("Matching TDI_SEND request not found\n");
-       KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock);
-       IoReleaseCancelSpinLock(OldIrql);
+       KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
        return ERR_ABRT;
+       
 FOUND:
        if (!Irp)
        {
                DPRINT1("Callback on cancelled IRP\n");
                RemoveEntryList(&Request->ListEntry);
                ExFreePoolWithTag(Request, TAG_TCP_REQUEST);
-               KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock);
-               IoReleaseCancelSpinLock(OldIrql);
+               KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
                return ERR_ABRT;
        }
        
@@ -630,13 +622,17 @@
                        IrpSp = IoGetCurrentIrpStackLocation(Irp);
                        RequestInfo = 
(PTDI_REQUEST_KERNEL_SEND)&IrpSp->Parameters;
                        lwip_err = tcp_write(Context->lwip_tcp_pcb, Buffer, 
RequestInfo->SendLength, 0);
+                       PrepareIrpForCancel(
+                               Irp,
+                               CancelRequestRoutine,
+                               TCP_REQUEST_CANCEL_MODE_PRESERVE,
+                               TCP_REQUEST_PENDING_SEND);
                        break;
                }
                Entry = Entry->Flink;
        }
        
-       KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock);
-       IoReleaseCancelSpinLock(OldIrql);
+       KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
        
        IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
        
@@ -657,8 +653,6 @@
        PNDIS_BUFFER Buffer;
        PTCP_CONTEXT Context;
        PTCP_REQUEST Request;
-       PIO_STACK_LOCATION IrpSp;
-       PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo;
        KIRQL OldIrql;
        
        INT CopiedLength;
@@ -669,172 +663,122 @@
        PLIST_ENTRY Head;
        PLIST_ENTRY Entry;
        NTSTATUS Status;
+       err_t lwip_err;
        
        DPRINT1("lwIP TCP Receive Callback\n");
        
-       if (err != ERR_OK)
+       /* This error is currently unimplemented in lwIP */
+/*     if (err != ERR_OK)
        {
                DPRINT1("lwIP Error %d\n", err);
                return ERR_ABRT;
-       }
-       
-       IoAcquireCancelSpinLock(&OldIrql);
+       }*/
        
        Context = (PTCP_CONTEXT)arg;
        DPRINT1("Context at %08x\n", Context);
        DPRINT1("AddressFile at %08x\n", Context->AddressFile);
-       if (!(Context->TcpState & TCP_STATE_RECEIVING))
-       {
+       if (!(Context->TcpState & TCP_STATE_RECEIVING)) {
                DPRINT1("Receive callback on connection that is not currently 
receiving\n");
-               IoReleaseCancelSpinLock(OldIrql);
                return ERR_ARG;
        }
-       KeAcquireSpinLockAtDpcLevel(&Context->RequestListLock);
+       KeAcquireSpinLock(&Context->RequestListLock, &OldIrql);
        Head = &Context->RequestListHead;
        Entry = Head->Flink;
        Irp = NULL;
-       while (Entry != Head)
-       {
+       DPRINT1("Entering Loop\n");
+       while (Entry != Head) {
+               DPRINT1("Fetching Request\n");
                Request = CONTAINING_RECORD(Entry, TCP_REQUEST, ListEntry);
-               if (!Request->PendingIrp)
-               {
+               DPRINT1("Request Fetched. Points to %08x\n", Request);
+               if (!Request->PendingIrp) {
+                       DPRINT1("IRP pointer dereferenced\n");
                        RemoveEntryList(Entry);
+                       DPRINT1("Entry removed\n");
                        Entry = Entry->Flink;
                        ExFreePoolWithTag(Request, TAG_TCP_REQUEST);
                        continue;
                }
-               if (Request->PendingMode == TCP_REQUEST_PENDING_RECEIVE)
-               {
+               if (Request->PendingMode == TCP_REQUEST_PENDING_RECEIVE) {
                        Irp = Request->PendingIrp;
                        Entry = Entry->Flink;
                        break;
                }
                Entry = Entry->Flink;
        }
-       if (!Irp)
-       {
+       if (!Irp) {
                DPRINT1("Receive callback on cancelled IRP\n");
-               KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock);
-               IoReleaseCancelSpinLock(OldIrql);
+               KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
                return ERR_ABRT;
        }
+       
+       /* IRP found, clear out the CANCEL flag */
        DPRINT1("IRP at %08x\n", Irp);
-       
-       IrpSp = IoGetCurrentIrpStackLocation(Irp);
-       DPRINT1("IrpSp: %08x\n", IrpSp);
-       
        IoSetCancelRoutine(Irp, NULL);
        Irp->Cancel = FALSE;
        
-       if (Context->lwip_tcp_pcb != tpcb)
-       {
+       if (Context->lwip_tcp_pcb != tpcb) {
                DPRINT1("Receive tcp_pcb mismatch\n");
                tcp_abort(tpcb);
+               InterlockedDecrement(&PcbCount);
+               DPRINT1("\n    PCB Count\n", PcbCount);
                
-               RemoveEntryList(&Request->ListEntry);
-               ExFreePoolWithTag(Request, TAG_TCP_REQUEST);
-               
-               KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock);
-               IoReleaseCancelSpinLock(OldIrql);
-               
-               Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
-               Irp->IoStatus.Information = 0;
-               IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
-               
-               return ERR_ABRT;
-       }
-       if (!(Context->TcpState & 
(TCP_STATE_RECEIVING|TCP_STATE_ACCEPTED|TCP_STATE_CONNECTED)))
-       {
+               // TODO: better return code
+               Status = STATUS_UNSUCCESSFUL;
+               CopiedLength = 0;
+               lwip_err = ERR_ABRT;
+               goto BAD;
+       }
+       if (!(Context->TcpState & 
(TCP_STATE_RECEIVING|TCP_STATE_ACCEPTED|TCP_STATE_CONNECTED))) {
                DPRINT1("Invalid TCP state: %08x\n", Context->TcpState);
-               
-               KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock);
-               IoReleaseCancelSpinLock(OldIrql);
-               
-               return ERR_ABRT;
+               // TODO: better return code
+               Status = STATUS_UNSUCCESSFUL;
+               lwip_err = ERR_ABRT;
+               goto BAD;
        }
        
        Buffer = (PNDIS_BUFFER)Irp->MdlAddress;
-       ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&IrpSp->Parameters;
-       
-       DPRINT1("NDIS Buffer: %08x\n", Buffer);
-       
-       if (Buffer->MdlFlags & 
(MDL_MAPPED_TO_SYSTEM_VA|MDL_SOURCE_IS_NONPAGED_POOL))
-       {
-               DPRINT1("Option 0\n");
-               CurrentDestLocation = Buffer->MappedSystemVa;
-       }
-       else
-       {
-               DPRINT1("Option 1\n");
-               CurrentDestLocation = MmMapLockedPages(Buffer, KernelMode);
-       }
-//     CurrentDestLocation = MmGetSystemAddressForMdl(Buffer);
-       RemainingDestBytes = Buffer->ByteCount;
-//     NdisQueryBuffer(Buffer, &CurrentDestLocation, &RemainingDestBytes);
-       
-       if (p)
-       {
-               DPRINT1("\n  PTDI_REQUEST_KERNEL_RECEIVE->ReceiveLength = %d\n  
NDIS_BUFFER length = %d\n  pbuf->tot_len = %d\n",
-                       ReceiveInfo->ReceiveLength,
-                       RemainingDestBytes,
-                       p->tot_len);
-       }
-       else
-       {
-               DPRINT1("\n  The pbuf pointer p is NULL\n");
-       }
-       
-       if (!p)
-       {
+       
+       NdisQueryBuffer(Buffer, &CurrentDestLocation, &RemainingDestBytes);
+       
+       if (!p) {
+               /* I believe this means the pcb was closed */
+               DPRINT1("NULL pbuf pointer\n");
                CopiedLength = 0;
                Status = STATUS_ADDRESS_CLOSED;
                goto BAD;
        }
        
-       if (RemainingDestBytes <= p->len)
-       {
+       if (RemainingDestBytes <= p->len) {
                RtlCopyMemory(CurrentDestLocation, p->payload, 
RemainingDestBytes);
                CopiedLength = RemainingDestBytes;
                Status = STATUS_SUCCESS;
                goto RETURN;
-       }
-       else
-       {
+       } else {
                CopiedLength = 0;
                RemainingSrceBytes = p->len;
                CurrentSrceLocation = p->payload;
                
-               while (1)
-               {
-                       if (RemainingSrceBytes < RemainingDestBytes)
-                       {
+               while (1) {
+                       if (RemainingSrceBytes < RemainingDestBytes) {
                                RtlCopyMemory(CurrentDestLocation, 
CurrentSrceLocation, RemainingSrceBytes);
                                
                                CopiedLength += p->len;
                                RemainingDestBytes -= p->len;
                                CurrentDestLocation += p->len;
                                
-                               if (p->next)
-                               {
+                               if (p->next) {
                                        RemainingSrceBytes = p->next->len;
                                        CurrentSrceLocation = p->next->payload;
-                                       
                                        pbuf_free(p);
                                        p = p->next;
-                                       
                                        continue;
-                               }
-                               else
-                               {
+                               } else {
                                        Status = STATUS_SUCCESS;
                                        goto RETURN;
                                }
-                       }
-                       else
-                       {
+                       } else {
                                RtlCopyMemory(CurrentDestLocation, 
CurrentSrceLocation, RemainingDestBytes);
                                CopiedLength += RemainingDestBytes;
-                               
                                Status = STATUS_SUCCESS;
                                goto RETURN;
                        }
@@ -845,29 +789,26 @@
        DPRINT1("Receive CopiedLength = %d\n", CopiedLength);
        
        tcp_recved(tpcb, CopiedLength);
-       
-       while (Entry != Head)
-       {
+       while (Entry != Head) {
                Request = CONTAINING_RECORD(Entry, TCP_REQUEST, ListEntry);
-               if (Request->PendingMode == TCP_REQUEST_PENDING_RECEIVE)
-               {
+               if (Request->PendingMode == TCP_REQUEST_PENDING_RECEIVE) {
                        tcp_recv(tpcb, lwip_tcp_receive_callback);
                        break;
                }
        }
+       lwip_err = ERR_OK;
        
 BAD:
        RemoveEntryList(&Request->ListEntry);
        ExFreePoolWithTag(Request, TAG_TCP_REQUEST);
        
-       KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock);
-       IoReleaseCancelSpinLock(OldIrql);
+       KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
        
        Irp->IoStatus.Status = Status;
        Irp->IoStatus.Information = CopiedLength;
        IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
        
-       return ERR_OK;
+       return lwip_err;
 }
 
 static
@@ -929,17 +870,18 @@
        KIRQL OldIrql;
        PLIST_ENTRY Head;
        PLIST_ENTRY Entry;
+       err_t lwip_err;
        
        DPRINT1("lwIP TCP Connected Callback\n");
        
-       IoAcquireCancelSpinLock(&OldIrql);
-       
        Context = (PTCP_CONTEXT)arg;
+       KeAcquireSpinLock(&Context->RequestListLock, &OldIrql);
        Head = &Context->RequestListHead;
        Entry = Head->Flink;
        if (Head == Entry)
        {
                DPRINT1("Request list is empty\n");
+               KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
                return ERR_ARG;
        }
        Request = CONTAINING_RECORD(Entry, TCP_REQUEST, ListEntry);
@@ -947,45 +889,37 @@
        if (!Irp)
        {
                DPRINT1("Callback on cancelled IRP\n");
-               
-               KeAcquireSpinLockAtDpcLevel(&Request->Context->RequestListLock);
                
                RemoveEntryList(&Request->ListEntry);
                ExFreePoolWithTag(Request, TAG_TCP_REQUEST);
                
-               
KeReleaseSpinLockFromDpcLevel(&Request->Context->RequestListLock);
-               IoReleaseCancelSpinLock(OldIrql);
+               KeReleaseSpinLock(&Request->Context->RequestListLock, OldIrql);
                
                return ERR_ABRT;
        }
-       
-       KeAcquireSpinLockAtDpcLevel(&Context->RequestListLock);
-       
-       if (Context->TcpState != TCP_STATE_CONNECTING)
-       {
-               DPRINT1("Invalid TCP state: %d\n", Context->TcpState);
-               
-               KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock);
-               IoReleaseCancelSpinLock(OldIrql);
-               
-               return ERR_ABRT;
-       }
-       
-       Context->TcpState = TCP_STATE_CONNECTED;
-       
        IoSetCancelRoutine(Irp, NULL);
        Irp->Cancel = FALSE;
+       if (Context->TcpState != TCP_STATE_CONNECTING)
+       {
+               DPRINT1("Invalid TCP state: %d\n", Context->TcpState);
+               lwip_err = ERR_ABRT;
+               goto FINISH;
+       }
+       
+       Context->TcpState = TCP_STATE_CONNECTED;
+       lwip_err = ERR_OK;
+       
+FINISH:
        
        RemoveEntryList(&Request->ListEntry);
        ExFreePoolWithTag(Request, TAG_TCP_REQUEST);
        
-       KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock);
-       IoReleaseCancelSpinLock(OldIrql);
+       KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
        
        Irp->IoStatus.Status = STATUS_SUCCESS;
        IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
        
-       return ERR_OK;
+       return lwip_err;
 }
 
 /* implementation in testing */
@@ -1006,6 +940,8 @@
     /* See if this port is already taken, and find a free one if needed. */
     KeAcquireSpinLock(&AddressListLock, &OldIrql);
 
+       DPRINT1("Search through used ports\n");
+       
     ListEntry = AddressListHead.Flink;
     while (ListEntry != &AddressListHead)
     {
@@ -1046,6 +982,8 @@
         ListEntry = ListEntry->Flink;
     }
 
+       DPRINT1("Find local interface for address\n");
+       
     if (!AddrIsUnspecified(Address))
     {
         /* Find the local interface for this address */
@@ -1071,6 +1009,8 @@
         }
     }
 
+       DPRINT1("Allocate address file\n");
+       
     /* Allocate our new address file */
     AddressFile = ExAllocatePoolWithTag(NonPagedPool, sizeof(*AddressFile), 
TAG_ADDRESS_FILE);
     if (!AddressFile)
@@ -1091,6 +1031,8 @@
     KeInitializeSpinLock(&AddressFile->RequestLock);
     InitializeListHead(&AddressFile->RequestListHead);
 
+       DPRINT1("Protocol-dependent operations\n");
+       
     /* Give it an entity ID and open a PCB if needed. */
     switch (Protocol)
     {
@@ -1101,6 +1043,8 @@
             InsertEntityInstance(CO_TL_ENTITY, &AddressFile->Instance);
                        AddressFile->ContextCount = 0;
                        AddressFile->lwip_tcp_pcb = tcp_new();
+                       InterlockedIncrement(&PcbCount);
+                       DPRINT1("\n    PCB Count: %d\n", PcbCount);
                        tcp_arg(AddressFile->lwip_tcp_pcb, AddressFile);
                        tcp_err(AddressFile->lwip_tcp_pcb, 
lwip_tcp_err_callback);
             break;
@@ -1140,6 +1084,8 @@
         }
     }
 
+       DPRINT1("Insert into address list\n");
+       
     /* Insert it into the list. */
     InsertTailList(&AddressListHead, &AddressFile->ListEntry);
     KeReleaseSpinLock(&AddressListLock, OldIrql);
@@ -1225,7 +1171,17 @@
                        }
                        if (AddressFile->lwip_tcp_pcb)
                        {
-                               lwip_err = tcp_close(AddressFile->lwip_tcp_pcb);
+                               if (AddressFile->lwip_tcp_pcb->state == LISTEN)
+                               {
+                                       lwip_err = 
tcp_close(AddressFile->lwip_tcp_pcb);
+                               }
+                               else
+                               {
+                                       tcp_abort(AddressFile->lwip_tcp_pcb);
+                                       lwip_err = ERR_OK;
+                               }
+                               InterlockedDecrement(&PcbCount);
+                               DPRINT1("\n    PCB Count: %d\n", PcbCount);
                                if (lwip_err != ERR_OK)
                                {
                                        DPRINT1("lwIP tcp_close error: %d", 
lwip_err);
@@ -1283,7 +1239,17 @@
        
        if (Context->lwip_tcp_pcb)
        {
-               lwip_err = tcp_close(Context->lwip_tcp_pcb);
+               if (Context->TcpState == TCP_STATE_LISTENING)
+               {
+                       lwip_err = tcp_close(Context->lwip_tcp_pcb);
+               }
+               else
+               {
+                       tcp_abort(Context->lwip_tcp_pcb);
+                       lwip_err = ERR_OK;
+               }
+               InterlockedDecrement(&PcbCount);
+               DPRINT1("\n    PCB Count: %d\n", PcbCount);
                if (lwip_err != ERR_OK)
                {
                        DPRINT1("lwIP tcp_close error: %d", lwip_err);
@@ -1384,14 +1350,15 @@
     NT_ASSERT(ListEntry != &AddressFile->RequestListHead);
 
     RemoveEntryList(&Request->ListEntry);
-    KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql);
 
     Irp->IoStatus.Status = STATUS_CANCELLED;
     Irp->IoStatus.Information = 0;
+       
+    KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql);
 
     IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
 
-    ExFreePoolWithTag(Request, TAG_TCP_REQUEST);
+    ExFreePoolWithTag(Request, TAG_DGRAM_REQST);
 }
 
 /* implementation in testing */
@@ -1625,14 +1592,13 @@
                                default :
                                {
                                        DPRINT1("lwIP unexpected error\n");
-                                       Status = STATUS_NOT_IMPLEMENTED;
+                                       // TODO: better return code
+                                       Status = STATUS_UNSUCCESSFUL;
                                        goto LEAVE;
                                }
                        }
                }
        }
-       
-       DPRINT1("TcpIpAssociateAddress Exiting\n");
        
        Context->TcpState = TCP_STATE_BOUND;
        
@@ -1679,14 +1645,12 @@
                return STATUS_INVALID_ADDRESS;
        }
        
-       KeAcquireSpinLock(&AddressFile->ContextListLock, &OldIrql);
-       
        if (AddressFile->lwip_tcp_pcb == Context->lwip_tcp_pcb)
        {
                Context->lwip_tcp_pcb = NULL;
        }
        
-       KeAcquireSpinLockAtDpcLevel(&Context->RequestListLock);
+       KeAcquireSpinLock(&Context->RequestListLock, &OldIrql);
        if (!(IsListEmpty(&Context->RequestListHead)))
        {
                DPRINT1("Disassociating context with outstanding requests\n");
@@ -1706,12 +1670,12 @@
                        }
                }
        }
-       KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock);
-       
+       KeReleaseSpinLock(&Context->RequestListLock, OldIrql);
+       
+       KeAcquireSpinLock(&AddressFile->ContextListLock, &OldIrql);
        RemoveEntryList(&Context->ListEntry);
        AddressFile->ContextCount--;
        Context->AddressFile = NULL;
-       
        KeReleaseSpinLock(&AddressFile->ContextListLock, OldIrql);
        
        if (AddressFile->ContextCount == 0)
@@ -1766,6 +1730,7 @@
                                either INVALID_ADDRESS or NO_MEMORY
                                if SO_REUSE is enabled in lwip options */
                        DPRINT1("lwip tcp_listen error\n");
+                       KeReleaseSpinLock(&AddressFile->ContextListLock, 
OldIrql);
                        return STATUS_INVALID_ADDRESS;
                }
                tcp_arg(lpcb, AddressFile);
@@ -1945,7 +1910,6 @@
     RECEIVE_DATAGRAM_REQUEST* Request = NULL;
     PTDI_REQUEST_KERNEL_RECEIVEDG RequestInfo;
     NTSTATUS Status;
-    KIRQL OldIrql;
 
     /* Check this is really an address file */
     if ((ULONG_PTR)IrpSp->FileObject->FsContext2 != TDI_TRANSPORT_ADDRESS_FILE)
@@ -1966,7 +1930,7 @@
     }
 
     /* Queue the request */
-    Request = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Request), 
TAG_TCP_REQUEST);
+    Request = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Request), 
TAG_DGRAM_REQST);
     if (!Request)
     {
         Status = STATUS_INSUFFICIENT_RESOURCES;
@@ -1997,14 +1961,10 @@
 
     Request->ReturnInfo = RequestInfo->ReturnDatagramInformation;
 
-    /* Prepare for potential cancellation */
-    IoAcquireCancelSpinLock(&OldIrql);
-    IoSetCancelRoutine(Irp, CancelReceiveDatagram);
-    IoReleaseCancelSpinLock(OldIrql);
-
     /* Mark pending */
     Irp->IoStatus.Status = STATUS_PENDING;
     IoMarkIrpPending(Irp);
+    IoSetCancelRoutine(Irp, CancelReceiveDatagram);
 
     /* We're ready to go */
     ExInterlockedInsertTailList(
@@ -2016,7 +1976,7 @@
 
 Failure:
     if (Request)
-        ExFreePoolWithTag(Request, TAG_TCP_REQUEST);
+        ExFreePoolWithTag(Request, TAG_DGRAM_REQST);
     Irp->IoStatus.Status = Status;
     IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
     return Status;

Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c?rev=71835&r1=71834&r2=71835&view=diff
==============================================================================
--- branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c  [iso-8859-1] 
(original)
+++ branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c  [iso-8859-1] 
Wed Jul  6 20:53:31 2016
@@ -269,7 +269,9 @@
                        DPRINT1("\nPTA_IP_ADDRESS dump before\n %08x %08x %08x 
%08x\n %08x %08x %08x %08x\n",
                                temp[7], temp[6], temp[5], temp[4],
                                temp[3], temp[2], temp[1], temp[0]);*/
+                       DPRINT1("Call into TcpIpCreateAddress\n");
                        Status = TcpIpCreateAddress(Irp, 
&Address->Address[0].Address[0], Protocol);
+                       DPRINT1("Returned from TcpIpCreateAddress\n");
                        if (Status != STATUS_SUCCESS)
                        {
                                goto Quickie;


Reply via email to