[ros-diffs] [cgutman] 44163: - Use a spin lock to protect OSKit instead of a recursive mutex - Remove the now unused recursive mutex code - Don't clear the SS_ISCONNECTING flag when soconnect returns EINPROGRESS because it causes a crash during soreceive - Lock CONNECTION_ENDPOINT and ADDRESS_FILE structs better - Remove incorrect IoMarkIrpPending calls - Remove useless ASSERT_LOCKED - Don't destroy so_connection when we close a connection - Remove useless FileFindConnectionByContext - Remove SignalledConnectionsList and SignalledConnectionsLock and simply loop through ConnectionEndpointList for signalled connections - Add connections to ConnectionEndpointList in TCPAllocateConnectionEndpoint instead of FileOpenConnection so we don't miss listeners - Remove connections from ConnectionEndpointList in TCPFreeConnectionEndpoint instead of FileCloseConnection so we don't miss listeners - Use ExInterlockedRemoveHeadList to remove entries in the address file's request lists - Remove useless members, flags, and variables in titypes.h and tcp.h - Fixes bug 4955 and 4434

cgutman at svn.reactos.org cgutman at svn.reactos.org
Sat Nov 14 19:38:02 CET 2009


Author: cgutman
Date: Sat Nov 14 19:38:02 2009
New Revision: 44163

URL: http://svn.reactos.org/svn/reactos?rev=44163&view=rev
Log:
 - Use a spin lock to protect OSKit instead of a recursive mutex
 - Remove the now unused recursive mutex code
 - Don't clear the SS_ISCONNECTING flag when soconnect returns EINPROGRESS because it causes a crash during soreceive
 - Lock CONNECTION_ENDPOINT and ADDRESS_FILE structs better
 - Remove incorrect IoMarkIrpPending calls
 - Remove useless ASSERT_LOCKED
 - Don't destroy so_connection when we close a connection
 - Remove useless FileFindConnectionByContext
 - Remove SignalledConnectionsList and SignalledConnectionsLock and simply loop through ConnectionEndpointList for signalled connections
 - Add connections to ConnectionEndpointList in TCPAllocateConnectionEndpoint instead of FileOpenConnection so we don't miss listeners
 - Remove connections from ConnectionEndpointList in TCPFreeConnectionEndpoint instead of FileCloseConnection so we don't miss listeners
 - Use ExInterlockedRemoveHeadList to remove entries in the address file's request lists
 - Remove useless members, flags, and variables in titypes.h and tcp.h
 - Fixes bug 4955 and 4434

Removed:
    trunk/reactos/drivers/network/tcpip/recmutex/
Modified:
    trunk/reactos/drivers/network/tcpip/include/fileobjs.h
    trunk/reactos/drivers/network/tcpip/include/tcp.h
    trunk/reactos/drivers/network/tcpip/include/titypes.h
    trunk/reactos/drivers/network/tcpip/tcpip.rbuild
    trunk/reactos/drivers/network/tcpip/tcpip/dispatch.c
    trunk/reactos/drivers/network/tcpip/tcpip/fileobjs.c
    trunk/reactos/drivers/network/tcpip/tcpip/lock.c
    trunk/reactos/drivers/network/tcpip/tcpip/mocklock.c
    trunk/reactos/lib/drivers/ip/transport/datagram/datagram.c
    trunk/reactos/lib/drivers/ip/transport/rawip/rawip.c
    trunk/reactos/lib/drivers/ip/transport/tcp/accept.c
    trunk/reactos/lib/drivers/ip/transport/tcp/event.c
    trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c
    trunk/reactos/lib/drivers/ip/transport/udp/udp.c
    trunk/reactos/lib/drivers/oskittcp/include/oskittcp.h
    trunk/reactos/lib/drivers/oskittcp/oskittcp/interface.c

Modified: trunk/reactos/drivers/network/tcpip/include/fileobjs.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/include/fileobjs.h?rev=44163&r1=44162&r2=44163&view=diff
==============================================================================
--- trunk/reactos/drivers/network/tcpip/include/fileobjs.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/tcpip/include/fileobjs.h [iso-8859-1] Sat Nov 14 19:38:02 2009
@@ -13,7 +13,6 @@
 extern LIST_ENTRY ConnectionEndpointListHead;
 extern KSPIN_LOCK ConnectionEndpointListLock;
 
-
 NTSTATUS FileOpenAddress(
   PTDI_REQUEST Request,
   PTA_IP_ADDRESS AddrList,
@@ -27,8 +26,6 @@
   PTDI_REQUEST Request,
   PVOID ClientContext);
 
-PCONNECTION_ENDPOINT FileFindConnectionByContext( PVOID Context );
-
 NTSTATUS FileCloseConnection(
   PTDI_REQUEST Request);
 

Modified: trunk/reactos/drivers/network/tcpip/include/tcp.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/include/tcp.h?rev=44163&r1=44162&r2=44163&view=diff
==============================================================================
--- trunk/reactos/drivers/network/tcpip/include/tcp.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/tcpip/include/tcp.h [iso-8859-1] Sat Nov 14 19:38:02 2009
@@ -84,11 +84,6 @@
 #define SRF_FIN   TCP_FIN
 
 extern LONG TCP_IPIdentification;
-extern LIST_ENTRY SignalledConnectionsList;
-extern KSPIN_LOCK SignalledConnectionsLock;
-extern LIST_ENTRY SleepingThreadsList;
-extern FAST_MUTEX SleepingThreadsLock;
-extern RECURSIVE_MUTEX TCPLock;
 
 /* accept.c */
 NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener,
@@ -105,7 +100,6 @@
   PVOID Context );
 
 /* tcp.c */
-ULONG HandleSignalledConnection( PCONNECTION_ENDPOINT Connection );
 PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext );
 VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection );
 

Modified: trunk/reactos/drivers/network/tcpip/include/titypes.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/include/titypes.h?rev=44163&r1=44162&r2=44163&view=diff
==============================================================================
--- trunk/reactos/drivers/network/tcpip/include/titypes.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/tcpip/include/titypes.h [iso-8859-1] Sat Nov 14 19:38:02 2009
@@ -153,7 +153,6 @@
     LIST_ENTRY ListEntry;                 /* Entry on list */
     KSPIN_LOCK Lock;                      /* Spin lock to manipulate this structure */
     OBJECT_FREE_ROUTINE Free;             /* Routine to use to free resources for the object */
-    USHORT Flags;                         /* Flags for address file (see below) */
     IP_ADDRESS Address;                   /* Address of this address file */
     USHORT Family;                        /* Address family */
     USHORT Protocol;                      /* Protocol number */
@@ -213,29 +212,6 @@
     BOOLEAN RegisteredChainedReceiveExpeditedHandler;
 } ADDRESS_FILE, *PADDRESS_FILE;
 
-/* Address File Flag constants */
-#define AFF_VALID    0x0001 /* Address file object is valid for use */
-#define AFF_BUSY     0x0002 /* Address file object is exclusive to someone */
-#define AFF_DELETE   0x0004 /* Address file object is sheduled to be deleted */
-#define AFF_SEND     0x0008 /* A send request is pending */
-#define AFF_RECEIVE  0x0010 /* A receive request is pending */
-#define AFF_PENDING  0x001C /* A request is pending */
-
-/* Macros for manipulating address file object flags */
-
-#define AF_IS_VALID(ADF)  ((ADF)->Flags & AFF_VALID)
-#define AF_SET_VALID(ADF) ((ADF)->Flags |= AFF_VALID)
-#define AF_CLR_VALID(ADF) ((ADF)->Flags &= ~AFF_VALID)
-
-#define AF_IS_BUSY(ADF)  ((ADF)->Flags & AFF_BUSY)
-#define AF_SET_BUSY(ADF) ((ADF)->Flags |= AFF_BUSY)
-#define AF_CLR_BUSY(ADF) ((ADF)->Flags &= ~AFF_BUSY)
-
-#define AF_IS_PENDING(ADF, X)  (ADF->Flags & X)
-#define AF_SET_PENDING(ADF, X) (ADF->Flags |= X)
-#define AF_CLR_PENDING(ADF, X) (ADF->Flags &= ~X)
-
-
 /* Structure used to search through Address Files */
 typedef struct _AF_SEARCH {
     PLIST_ENTRY Next;       /* Next address file to check */
@@ -306,8 +282,6 @@
     LIST_ENTRY SendRequest;    /* Queued send requests */
 
     /* Signals */
-    LIST_ENTRY SignalList;     /* Entry in the list of sockets waiting for
-				* notification service to the client */
     UINT    SignalState;       /* Active signals from oskit */
 } CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT;
 

Modified: trunk/reactos/drivers/network/tcpip/tcpip.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/tcpip.rbuild?rev=44163&r1=44162&r2=44163&view=diff
==============================================================================
--- trunk/reactos/drivers/network/tcpip/tcpip.rbuild [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/tcpip/tcpip.rbuild [iso-8859-1] Sat Nov 14 19:38:02 2009
@@ -21,9 +21,6 @@
 	<directory name="datalink">
 		<file>lan.c</file>
 	</directory>
-	<directory name="recmutex">
-		<file>recmutex.c</file>
-	</directory>
 	<directory name="tcpip">
 		<file>ainfo.c</file>
 		<file>buffer.c</file>

Modified: trunk/reactos/drivers/network/tcpip/tcpip/dispatch.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/tcpip/dispatch.c?rev=44163&r1=44162&r2=44163&view=diff
==============================================================================
--- trunk/reactos/drivers/network/tcpip/tcpip/dispatch.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/tcpip/tcpip/dispatch.c [iso-8859-1] Sat Nov 14 19:38:02 2009
@@ -210,9 +210,8 @@
 
     TCPRemoveIRP(Connection, Irp);
 
-    TCPAbortListenForSocket(
-	    Connection->AddressFile->Listener,
-	    Connection );
+    TCPAbortListenForSocket(Connection->AddressFile->Listener,
+                            Connection);
 
     IoReleaseCancelSpinLock(Irp->CancelIrql);
 
@@ -1044,7 +1043,7 @@
   Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters;
   Status     = STATUS_SUCCESS;
 
-  TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+  KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
 
   /* Set the event handler. if an event handler is associated with
      a specific event, it's flag (RegisteredXxxHandler) is TRUE.
@@ -1165,7 +1164,7 @@
     Status = STATUS_INVALID_PARAMETER;
   }
 
-  TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
+  KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
 
   return Status;
 }

Modified: trunk/reactos/drivers/network/tcpip/tcpip/fileobjs.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/tcpip/fileobjs.c?rev=44163&r1=44162&r2=44163&view=diff
==============================================================================
--- trunk/reactos/drivers/network/tcpip/tcpip/fileobjs.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/tcpip/tcpip/fileobjs.c [iso-8859-1] Sat Nov 14 19:38:02 2009
@@ -295,9 +295,6 @@
   /* Initialize spin lock that protects the address file object */
   KeInitializeSpinLock(&AddrFile->Lock);
 
-  /* Set valid flag so the address can be used */
-  AF_SET_VALID(AddrFile);
-
   /* Return address file object */
   Request->Handle.AddressHandle = AddrFile;
 
@@ -328,7 +325,7 @@
   KIRQL OldIrql;
   PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
   PDATAGRAM_SEND_REQUEST SendRequest;
-  PLIST_ENTRY CurrentEntry, NextEntry;
+  PLIST_ENTRY CurrentEntry;
 
   AddrFile = Request->Handle.AddressHandle;
 
@@ -339,8 +336,6 @@
   RemoveEntryList(&AddrFile->ListEntry);
   TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
 
-  TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
-
   /* FIXME: Kill TCP connections on this address file object */
 
   /* Return pending requests with error */
@@ -348,43 +343,27 @@
   TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting receive requests on AddrFile at (0x%X).\n", AddrFile));
 
   /* Go through pending receive request list and cancel them all */
-  CurrentEntry = AddrFile->ReceiveQueue.Flink;
-  while (CurrentEntry != &AddrFile->ReceiveQueue) {
-    NextEntry = CurrentEntry->Flink;
+  while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) {
     ReceiveRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
-    /* Abort the request and free its resources */
-    TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
     (*ReceiveRequest->Complete)(ReceiveRequest->Context, STATUS_CANCELLED, 0);
-    TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
-    CurrentEntry = NextEntry;
+    /* exFreePool(ReceiveRequest); FIXME: WTF? */
   }
 
   TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting send requests on address file at (0x%X).\n", AddrFile));
 
   /* Go through pending send request list and cancel them all */
-  CurrentEntry = AddrFile->TransmitQueue.Flink;
-  while (CurrentEntry != &AddrFile->TransmitQueue) {
-    NextEntry = CurrentEntry->Flink;
-    SendRequest = CONTAINING_RECORD(CurrentEntry,
-				    DATAGRAM_SEND_REQUEST, ListEntry);
-    /* Abort the request and free its resources */
-    TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
+  while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) {
+    SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
     (*SendRequest->Complete)(SendRequest->Context, STATUS_CANCELLED, 0);
     exFreePool(SendRequest);
-    TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
-    CurrentEntry = NextEntry;
-  }
-
-  TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
+  }
 
   /* Protocol specific handling */
   switch (AddrFile->Protocol) {
   case IPPROTO_TCP:
     TCPFreePort( AddrFile->Port );
-    if( AddrFile->Listener ) {
-	    TCPClose( AddrFile->Listener );
-	    exFreePool( AddrFile->Listener );
-    }
+    if( AddrFile->Listener )
+	TCPClose( AddrFile->Listener );
     break;
 
   case IPPROTO_UDP:
@@ -433,46 +412,9 @@
   /* Return connection endpoint file object */
   Request->Handle.ConnectionContext = Connection;
 
-  /* Add connection endpoint to global list */
-  ExInterlockedInsertTailList(
-    &ConnectionEndpointListHead,
-    &Connection->ListEntry,
-    &ConnectionEndpointListLock);
-
   TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
 
   return STATUS_SUCCESS;
-}
-
-
-/*
- * FUNCTION: Find a connection by examining the context field.  This
- * is needed in some situations where a FIN reply is needed after a
- * socket is formally broken.
- * ARGUMENTS:
- *     Request = Pointer to TDI request structure for this request
- * RETURNS:
- *     Status of operation
- */
-PCONNECTION_ENDPOINT FileFindConnectionByContext( PVOID Context ) {
-    PLIST_ENTRY Entry;
-    KIRQL OldIrql;
-    PCONNECTION_ENDPOINT Connection = NULL;
-
-    TcpipAcquireSpinLock( &ConnectionEndpointListLock, &OldIrql );
-
-    for( Entry = ConnectionEndpointListHead.Flink;
-	 Entry != &ConnectionEndpointListHead;
-	 Entry = Entry->Flink ) {
-	Connection =
-	    CONTAINING_RECORD( Entry, CONNECTION_ENDPOINT, ListEntry );
-	if( Connection->SocketContext == Context ) break;
-	else Connection = NULL;
-    }
-
-    TcpipReleaseSpinLock( &ConnectionEndpointListLock, OldIrql );
-
-    return Connection;
 }
 
 /*
@@ -486,19 +428,12 @@
   PTDI_REQUEST Request)
 {
   PCONNECTION_ENDPOINT Connection;
-  KIRQL OldIrql;
 
   TI_DbgPrint(MID_TRACE, ("Called.\n"));
 
   Connection = Request->Handle.ConnectionContext;
 
-  TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
-  RemoveEntryList(&Connection->ListEntry);
-  TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
-
   TCPClose( Connection );
-
-  TCPFreeConnectionEndpoint(Connection);
 
   TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
 

Modified: trunk/reactos/drivers/network/tcpip/tcpip/lock.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/tcpip/lock.c?rev=44163&r1=44162&r2=44163&view=diff
==============================================================================
--- trunk/reactos/drivers/network/tcpip/tcpip/lock.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/tcpip/tcpip/lock.c [iso-8859-1] Sat Nov 14 19:38:02 2009
@@ -44,16 +44,3 @@
     ExReleaseFastMutex( Mutex );
 }
 
-VOID TcpipRecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) {
-    RecursiveMutexInit( RecMutex );
-}
-
-VOID TcpipRecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex ) {
-    //TI_DbgPrint(DEBUG_LOCK,("Locking\n"));
-    RecursiveMutexEnter( RecMutex );
-}
-
-VOID TcpipRecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ) {
-    //TI_DbgPrint(DEBUG_LOCK,("Unlocking\n"));
-    RecursiveMutexLeave( RecMutex );
-}

Modified: trunk/reactos/drivers/network/tcpip/tcpip/mocklock.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/tcpip/mocklock.c?rev=44163&r1=44162&r2=44163&view=diff
==============================================================================
--- trunk/reactos/drivers/network/tcpip/tcpip/mocklock.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/tcpip/tcpip/mocklock.c [iso-8859-1] Sat Nov 14 19:38:02 2009
@@ -45,11 +45,3 @@
 VOID TcpipReleaseFastMutex( PFAST_MUTEX Mutex ) {
 }
 
-VOID TcpipRecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) {
-}
-
-VOID TcpipRecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex ) {
-}
-
-VOID TcpipRecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ) {
-}

Modified: trunk/reactos/lib/drivers/ip/transport/datagram/datagram.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/transport/datagram/datagram.c?rev=44163&r1=44162&r2=44163&view=diff
==============================================================================
--- trunk/reactos/lib/drivers/ip/transport/datagram/datagram.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/ip/transport/datagram/datagram.c [iso-8859-1] Sat Nov 14 19:38:02 2009
@@ -79,7 +79,7 @@
 
   TI_DbgPrint(MAX_TRACE, ("Called.\n"));
 
-  TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+  KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
 
   if (AddrFile->Protocol == IPPROTO_UDP)
     {
@@ -136,7 +136,7 @@
 			     &SrcAddress->Address.IPv4Address,
 			     sizeof(SrcAddress->Address.IPv4Address) );
 
-              TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
+              KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
 
               /* Complete the receive request */
               if (Current->BufferSize < DataSize)
@@ -144,11 +144,11 @@
               else
                   Current->Complete(Current->Context, STATUS_SUCCESS, DataSize);
 
-              TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+              KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
 	  }
       }
 
-      TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
+      KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
     }
   else if (AddrFile->RegisteredReceiveDatagramHandler)
     {
@@ -157,8 +157,6 @@
       ReceiveHandler = AddrFile->ReceiveDatagramHandler;
       HandlerContext = AddrFile->ReceiveDatagramHandlerContext;
 
-      TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
-
       if (SrcAddress->Type == IP_ADDRESS_V4)
         {
           AddressLength = sizeof(IPv4_RAW_ADDRESS);
@@ -169,6 +167,8 @@
           AddressLength = sizeof(IPv6_RAW_ADDRESS);
           SourceAddress = SrcAddress->Address.IPv6Address;
         }
+
+      KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
 
       Status = (*ReceiveHandler)(HandlerContext,
         AddressLength,
@@ -184,7 +184,7 @@
     }
   else
     {
-      TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
+      KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
       TI_DbgPrint(MAX_TRACE, ("Discarding datagram.\n"));
     }
 
@@ -228,75 +228,66 @@
  *     This is the high level interface for receiving DG datagrams
  */
 {
-    KIRQL OldIrql;
     NTSTATUS Status;
     PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
+    KIRQL OldIrql;
 
     TI_DbgPrint(MAX_TRACE, ("Called.\n"));
 
-    TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
-
-    if (AF_IS_VALID(AddrFile))
-    {
-	ReceiveRequest = exAllocatePool(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST));
-	if (ReceiveRequest)
-        {
-	    /* Initialize a receive request */
-
-	    /* Extract the remote address filter from the request (if any) */
-	    if ((ConnInfo->RemoteAddressLength != 0) &&
-		(ConnInfo->RemoteAddress))
+    KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+
+    ReceiveRequest = exAllocatePool(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST));
+    if (ReceiveRequest)
+    {
+	/* Initialize a receive request */
+
+	/* Extract the remote address filter from the request (if any) */
+	if ((ConnInfo->RemoteAddressLength != 0) &&
+	    (ConnInfo->RemoteAddress))
+        {
+	    Status = AddrGetAddress(ConnInfo->RemoteAddress,
+				    &ReceiveRequest->RemoteAddress,
+				    &ReceiveRequest->RemotePort);
+	    if (!NT_SUCCESS(Status))
             {
-		Status = AddrGetAddress(ConnInfo->RemoteAddress,
-					&ReceiveRequest->RemoteAddress,
-					&ReceiveRequest->RemotePort);
-		if (!NT_SUCCESS(Status))
-                {
-		    TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
-		    exFreePool(ReceiveRequest);
-		    return Status;
-                }
+		exFreePool(ReceiveRequest);
+	        KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+		return Status;
             }
-	    else
-            {
-		ReceiveRequest->RemotePort = 0;
-		AddrInitIPv4(&ReceiveRequest->RemoteAddress, 0);
-            }
-
-	    IoMarkIrpPending(Irp);
-
-	    ReceiveRequest->ReturnInfo = ReturnInfo;
-	    ReceiveRequest->Buffer = BufferData;
-	    ReceiveRequest->BufferSize = ReceiveLength;
-	    ReceiveRequest->UserComplete = Complete;
-	    ReceiveRequest->UserContext = Context;
-	    ReceiveRequest->Complete =
+	}
+	else
+        {
+	    ReceiveRequest->RemotePort = 0;
+	    AddrInitIPv4(&ReceiveRequest->RemoteAddress, 0);
+        }
+
+	IoMarkIrpPending(Irp);
+
+	ReceiveRequest->ReturnInfo = ReturnInfo;
+	ReceiveRequest->Buffer = BufferData;
+	ReceiveRequest->BufferSize = ReceiveLength;
+	ReceiveRequest->UserComplete = Complete;
+	ReceiveRequest->UserContext = Context;
+	ReceiveRequest->Complete =
 		(PDATAGRAM_COMPLETION_ROUTINE)DGReceiveComplete;
-	    ReceiveRequest->Context = ReceiveRequest;
-            ReceiveRequest->AddressFile = AddrFile;
-            ReceiveRequest->Irp = Irp;
-
-	    /* Queue receive request */
-	    InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry);
-	    AF_SET_PENDING(AddrFile, AFF_RECEIVE);
-
-	    TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
-
-	    TI_DbgPrint(MAX_TRACE, ("Leaving (pending %08x).\n", ReceiveRequest));
-
-	    return STATUS_PENDING;
-        }
-	else
-        {
-	    Status = STATUS_INSUFFICIENT_RESOURCES;
-        }
+	ReceiveRequest->Context = ReceiveRequest;
+        ReceiveRequest->AddressFile = AddrFile;
+        ReceiveRequest->Irp = Irp;
+
+	/* Queue receive request */
+	InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry);
+
+	TI_DbgPrint(MAX_TRACE, ("Leaving (pending %08x).\n", ReceiveRequest));
+
+	KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+
+	return STATUS_PENDING;
     }
     else
     {
-	Status = STATUS_INVALID_ADDRESS;
-    }
-
-    TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
+	KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+    }
 
     TI_DbgPrint(MAX_TRACE, ("Leaving with errors (0x%X).\n", Status));
 

Modified: trunk/reactos/lib/drivers/ip/transport/rawip/rawip.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/transport/rawip/rawip.c?rev=44163&r1=44162&r2=44163&view=diff
==============================================================================
--- trunk/reactos/lib/drivers/ip/transport/rawip/rawip.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/ip/transport/rawip/rawip.c [iso-8859-1] Sat Nov 14 19:38:02 2009
@@ -195,6 +195,9 @@
     USHORT RemotePort;
     NTSTATUS Status;
     PNEIGHBOR_CACHE_ENTRY NCE;
+    KIRQL OldIrql;
+
+    KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
 
     TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n",
 			   AddrFile, ConnInfo, BufferData, DataSize));
@@ -209,13 +212,17 @@
 	break;
 
     default:
+	KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
 	return STATUS_UNSUCCESSFUL;
     }
 
     TI_DbgPrint(MID_TRACE,("About to get route to destination\n"));
 
     if(!(NCE = RouteGetRouteToDestination( &RemoteAddress )))
+    {
+	KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
 	return STATUS_NETWORK_UNREACHABLE;
+    }
 
     LocalAddress = AddrFile->Address;
     if (AddrIsUnspecified(&LocalAddress))
@@ -237,17 +244,23 @@
                                DataSize );
 
     if( !NT_SUCCESS(Status) )
+    {
+	KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
 	return Status;
+    }
 
     TI_DbgPrint(MID_TRACE,("About to send datagram\n"));
 
     if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, RawIpSendPacketComplete, NULL )))
     {
+	KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
         FreeNdisPacket(Packet.NdisPacket);
         return Status;
     }
 
     TI_DbgPrint(MID_TRACE,("Leaving\n"));
+
+    KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
 
     return STATUS_SUCCESS;
 }

Modified: trunk/reactos/lib/drivers/ip/transport/tcp/accept.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/transport/tcp/accept.c?rev=44163&r1=44162&r2=44163&view=diff
==============================================================================
--- trunk/reactos/lib/drivers/ip/transport/tcp/accept.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/ip/transport/tcp/accept.c [iso-8859-1] Sat Nov 14 19:38:02 2009
@@ -10,6 +10,7 @@
 
 #include "precomp.h"
 
+/* Listener->Lock MUST be acquired */
 NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener,
                     PCONNECTION_ENDPOINT Connection,
                     PTDI_REQUEST_KERNEL Request ) {
@@ -26,17 +27,14 @@
     WhoIsConnecting = (PTDI_CONNECTION_INFORMATION)
     Request->ReturnConnectionInformation;
 
-    TcpipRecursiveMutexEnter(&TCPLock);
-
     Status = TCPTranslateError
     ( OskitTCPAccept( Listener->SocketContext,
               &Connection->SocketContext,
+              Connection,
               &OutAddr,
               sizeof(OutAddr),
               &OutAddrLen,
               Request->RequestFlags & TDI_QUERY_ACCEPT ? 0 : 1 ) );
-
-    TcpipRecursiveMutexLeave(&TCPLock);
 
     TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status));
 
@@ -71,10 +69,13 @@
 NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) {
     NTSTATUS Status = STATUS_SUCCESS;
     SOCKADDR_IN AddressToBind;
+    KIRQL OldIrql;
 
     ASSERT(Connection);
     ASSERT_KM_POINTER(Connection->SocketContext);
     ASSERT_KM_POINTER(Connection->AddressFile);
+
+    KeAcquireSpinLock(&Connection->Lock, &OldIrql);
 
     TI_DbgPrint(DEBUG_TCP,("TCPListen started\n"));
 
@@ -89,8 +90,6 @@
 
     TI_DbgPrint(DEBUG_TCP,("AddressToBind - %x:%x\n", AddressToBind.sin_addr, AddressToBind.sin_port));
 
-    TcpipRecursiveMutexEnter( &TCPLock );
-
     Status = TCPTranslateError( OskitTCPBind( Connection->SocketContext,
                         &AddressToBind,
                         sizeof(AddressToBind) ) );
@@ -98,7 +97,7 @@
     if (NT_SUCCESS(Status))
         Status = TCPTranslateError( OskitTCPListen( Connection->SocketContext, Backlog ) );
 
-    TcpipRecursiveMutexLeave( &TCPLock );
+    KeReleaseSpinLock(&Connection->Lock, OldIrql);
 
     TI_DbgPrint(DEBUG_TCP,("TCPListen finished %x\n", Status));
 
@@ -137,11 +136,16 @@
 {
     NTSTATUS Status;
     PTDI_BUCKET Bucket;
+    KIRQL OldIrql;
 
     TI_DbgPrint(DEBUG_TCP,("TCPAccept started\n"));
 
+    KeAcquireSpinLock(&Listener->Lock, &OldIrql);
+
     Status = TCPServiceListeningSocket( Listener, Connection,
                        (PTDI_REQUEST_KERNEL)Request );
+
+    KeReleaseSpinLock(&Listener->Lock, OldIrql);
 
     if( Status == STATUS_PENDING ) {
         Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) );
@@ -150,8 +154,8 @@
             Bucket->AssociatedEndpoint = Connection;
             Bucket->Request.RequestNotifyObject = Complete;
             Bucket->Request.RequestContext = Context;
-            IoMarkIrpPending((PIRP)Context);
-            ExInterlockedInsertTailList( &Listener->ListenRequest, &Bucket->Entry, &Listener->Lock );
+            ExInterlockedInsertTailList( &Listener->ListenRequest, &Bucket->Entry,
+                                         &Listener->Lock );
         } else
             Status = STATUS_NO_MEMORY;
     }

Modified: trunk/reactos/lib/drivers/ip/transport/tcp/event.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/transport/tcp/event.c?rev=44163&r1=44162&r2=44163&view=diff
==============================================================================
--- trunk/reactos/lib/drivers/ip/transport/tcp/event.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/ip/transport/tcp/event.c [iso-8859-1] Sat Nov 14 19:38:02 2009
@@ -15,56 +15,30 @@
            void *WhichConnection,
            OSK_UINT NewState ) {
     PCONNECTION_ENDPOINT Connection = WhichConnection;
-    ULONG OldState;
-    KIRQL OldIrql;
-
-    ASSERT_LOCKED(&TCPLock);
-
-    TI_DbgPrint(MID_TRACE,("Flags: %c%c%c%c\n",
+
+    TI_DbgPrint(DEBUG_TCP,("Connection: %x Flags: %c%c%c%c%c\n",
+               Connection,
                NewState & SEL_CONNECT ? 'C' : 'c',
                NewState & SEL_READ    ? 'R' : 'r',
                NewState & SEL_FIN     ? 'F' : 'f',
-               NewState & SEL_ACCEPT  ? 'A' : 'a'));
+               NewState & SEL_ACCEPT  ? 'A' : 'a',
+               NewState & SEL_WRITE   ? 'W' : 'w'));
+
+    if (!Connection)
+    {
+        return 0;
+    }
+
+    KeAcquireSpinLockAtDpcLevel(&Connection->Lock);
 
     TI_DbgPrint(DEBUG_TCP,("Called: NewState %x (Conn %x) (Change %x)\n",
                NewState, Connection,
-               Connection ? Connection->SignalState ^ NewState :
+               Connection->SignalState ^ NewState,
                NewState));
 
-    if( !Connection ) {
-    TI_DbgPrint(DEBUG_TCP,("Socket closing.\n"));
-    Connection = FileFindConnectionByContext( WhichSocket );
-    if( !Connection )
-        return 0;
-    else
-        TI_DbgPrint(DEBUG_TCP,("Found socket %x\n", Connection));
-    }
-
-    OldState = Connection->SignalState;
-
     Connection->SignalState |= NewState;
 
-    TcpipRecursiveMutexLeave(&TCPLock);
-
-    /* We must not be locked when handling signalled connections 
-     * because a completion could trigger another IOCTL which
-     * would cause a deadlock
-     */
-    NewState = HandleSignalledConnection(Connection);
-
-    TcpipRecursiveMutexEnter(&TCPLock);
-
-    KeAcquireSpinLock(&SignalledConnectionsLock, &OldIrql);
-    if ((NewState == 0 || NewState == SEL_FIN) &&
-        (OldState != 0 && OldState != SEL_FIN))
-    {
-        RemoveEntryList(&Connection->SignalList);
-    }
-    else if (NewState != 0 && NewState != SEL_FIN)
-    {
-        InsertTailList(&SignalledConnectionsList, &Connection->SignalList);
-    }
-    KeReleaseSpinLock(&SignalledConnectionsLock, OldIrql);
+    KeReleaseSpinLockFromDpcLevel(&Connection->Lock);
 
     return 0;
 }
@@ -85,8 +59,6 @@
     IP_PACKET Packet = { 0 };
     IP_ADDRESS RemoteAddress, LocalAddress;
     PIPv4_HEADER Header;
-
-    ASSERT_LOCKED(&TCPLock);
 
     if( *data == 0x45 ) { /* IPv4 */
     Header = (PIPv4_HEADER)data;
@@ -180,8 +152,6 @@
          OSK_UINT Bytes, OSK_PCHAR File, OSK_UINT Line ) {
     void *v;
     ULONG Signature;
-
-    ASSERT_LOCKED(&TCPLock);
 
 #if 0 != MEM_PROFILE
     static OSK_UINT *Sizes = NULL, *Counts = NULL, ArrayAllocated = 0;
@@ -258,8 +228,6 @@
           void *data, OSK_PCHAR File, OSK_UINT Line ) {
     ULONG Signature;
 
-    ASSERT_LOCKED(&TCPLock);
-
     UntrackFL( (PCHAR)File, Line, data, FOURCC('f','b','s','d') );
     data = (void *)((char *) data - sizeof(ULONG));
     Signature = *((ULONG *) data);

Modified: trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c?rev=44163&r1=44162&r2=44163&view=diff
==============================================================================
--- trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c [iso-8859-1] Sat Nov 14 19:38:02 2009
@@ -15,12 +15,12 @@
 LONG TCP_IPIdentification = 0;
 static BOOLEAN TCPInitialized = FALSE;
 static NPAGED_LOOKASIDE_LIST TCPSegmentList;
-LIST_ENTRY SignalledConnectionsList;
-KSPIN_LOCK SignalledConnectionsLock;
-RECURSIVE_MUTEX TCPLock;
 PORT_SET TCPPorts;
 
-ULONG HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) {
+static VOID DrainSignals() {
+    PCONNECTION_ENDPOINT Connection;
+    PLIST_ENTRY CurrentEntry, NextEntry;
+    KIRQL OldIrql;
     NTSTATUS Status = STATUS_SUCCESS;
     PTCP_COMPLETION_ROUTINE Complete;
     PTDI_BUCKET Bucket;
@@ -28,279 +28,290 @@
     PIRP Irp;
     PMDL Mdl;
 
-    TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n",
-                           Connection, Connection->SocketContext));
-
-    if( Connection->SignalState & SEL_FIN ) {
-        TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n"));
-
-        Connection->SignalState &= ~SEL_READ;
-        while ((Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest,
-                                                     &Connection->Lock )) != NULL)
-        {
-           Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-           Complete = Bucket->Request.RequestNotifyObject;
-
-           Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
-
-           exFreePool(Bucket);
-        }
-
-        Connection->SignalState &= ~SEL_WRITE;
-        while ((Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest,
-                                                     &Connection->Lock )) != NULL)
-        {
-           Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-           Complete = Bucket->Request.RequestNotifyObject;
-
-           Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
-
-           exFreePool(Bucket);
-        }
-
-        Connection->SignalState &= ~SEL_ACCEPT;
-        while ((Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest,
-                                                     &Connection->Lock )) != NULL)
-        {
-           Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-           Complete = Bucket->Request.RequestNotifyObject;
-
-           /* We have to notify oskittcp of the abortion */
-           TCPAbortListenForSocket(Connection->AddressFile->Listener,
-                               Connection);
-
-           Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
-
-           exFreePool(Bucket);
-        }
-
-        Connection->SignalState &= ~SEL_CONNECT;
-        while ((Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest,
-                                                     &Connection->Lock )) != NULL)
-        {
-           Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-           Complete = Bucket->Request.RequestNotifyObject;
-
-           Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
-
-           exFreePool(Bucket);
-        }
-    }
-
-    /* Things that can happen when we try the initial connection */
-    if( Connection->SignalState & SEL_CONNECT ) {
-        Connection->SignalState &= ~SEL_CONNECT;
-        while( (Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest,
-                                                     &Connection->Lock )) != NULL ) {
+    KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
+    CurrentEntry = ConnectionEndpointListHead.Flink;
+    while (CurrentEntry != &ConnectionEndpointListHead)
+    {
+        NextEntry = CurrentEntry->Flink;
+        KeReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
+
+        Connection = CONTAINING_RECORD( CurrentEntry, CONNECTION_ENDPOINT,
+                                        ListEntry );
+
+        KeAcquireSpinLock(&Connection->Lock, &OldIrql);
+
+        TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n",
+                               Connection, Connection->SocketContext));
+
+        if( !Connection->SocketContext || Connection->SignalState & SEL_FIN ) {
+            KeReleaseSpinLock(&Connection->Lock, OldIrql);
+            TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n"));
+
+            while ((Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest,
+                                                         &Connection->Lock )) != NULL)
+            {
+               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+               Complete = Bucket->Request.RequestNotifyObject;
+
+               Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
+
+               exFreePool(Bucket);
+            }
+
+            while ((Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest,
+                                                         &Connection->Lock )) != NULL)
+            {
+               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+               Complete = Bucket->Request.RequestNotifyObject;
+
+               Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
+
+               exFreePool(Bucket);
+            }
+
+            while ((Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest,
+                                                         &Connection->Lock )) != NULL)
+            {
+               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+               Complete = Bucket->Request.RequestNotifyObject;
+
+               Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
+
+               exFreePool(Bucket);
+            }
+
+            while ((Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest,
+                                                         &Connection->Lock )) != NULL)
+            {
+               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+               Complete = Bucket->Request.RequestNotifyObject;
+
+               Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
+
+               exFreePool(Bucket);
+            }
+
+            KeAcquireSpinLock(&Connection->Lock, &OldIrql);
+        }
+
+        /* Things that can happen when we try the initial connection */
+        if( Connection->SignalState & SEL_CONNECT ) {
+            KeReleaseSpinLock(&Connection->Lock, OldIrql);
+            while( (Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest,
+                                                         &Connection->Lock )) != NULL ) {
             
-            TI_DbgPrint(DEBUG_TCP, ("Connect Event\n"));
-
-            Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-            Complete = Bucket->Request.RequestNotifyObject;
-            TI_DbgPrint(DEBUG_TCP,
-                        ("Completing Request %x\n", Bucket->Request.RequestContext));
-
-            Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 );
-
-            /* Frees the bucket allocated in TCPConnect */
-            exFreePool( Bucket );
-        }
-    }
-
-    if( Connection->SignalState & SEL_ACCEPT ) {
-        /* Handle readable on a listening socket --
-         * TODO: Implement filtering
-         */
-
-        TI_DbgPrint(DEBUG_TCP,("Accepting new connection on %x (Queue: %s)\n",
-                               Connection,
-                               IsListEmpty(&Connection->ListenRequest) ?
-                               "empty" : "nonempty"));
-
-        Connection->SignalState &= ~SEL_ACCEPT;
-        while( (Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest,
-                                                     &Connection->Lock )) != NULL ) {
-            PIO_STACK_LOCATION IrpSp;
-
-            Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-            Complete = Bucket->Request.RequestNotifyObject;
-
-            Irp = Bucket->Request.RequestContext;
-            IrpSp = IoGetCurrentIrpStackLocation( Irp );
-
-            TI_DbgPrint(DEBUG_TCP,("Getting the socket\n"));
-            Status = TCPServiceListeningSocket
-                ( Connection->AddressFile->Listener,
-                  Bucket->AssociatedEndpoint,
-                  (PTDI_REQUEST_KERNEL)&IrpSp->Parameters );
-
-            TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n"));
-
-            if( Status == STATUS_PENDING ) {
-                Connection->SignalState |= SEL_ACCEPT;
-                ExInterlockedInsertHeadList( &Connection->ListenRequest, &Bucket->Entry, &Connection->Lock );
-                break;
-            } else {
-                Complete( Bucket->Request.RequestContext, Status, 0 );
-                exFreePool( Bucket );
-            }
-        }
-    }
-
-    /* Things that happen after we're connected */
-    if( Connection->SignalState & SEL_READ ) {
-        TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n",
-                               IsListEmpty(&Connection->ReceiveRequest) ?
-                               "empty" : "nonempty"));
-
-        Connection->SignalState &= ~SEL_READ;
-        while( (Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest,
-                                                     &Connection->Lock )) != NULL ) {
-            OSK_UINT RecvLen = 0, Received = 0;
-            PVOID RecvBuffer = 0;
-
-            Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-            Complete = Bucket->Request.RequestNotifyObject;
-
-            Irp = Bucket->Request.RequestContext;
-            Mdl = Irp->MdlAddress;
-
-            TI_DbgPrint(DEBUG_TCP,
-                        ("Getting the user buffer from %x\n", Mdl));
-
-            NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen );
-
-            TI_DbgPrint(DEBUG_TCP,
-                        ("Reading %d bytes to %x\n", RecvLen, RecvBuffer));
-
-            TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
-            TI_DbgPrint
+               TI_DbgPrint(DEBUG_TCP, ("Connect Event\n"));
+
+               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+               Complete = Bucket->Request.RequestNotifyObject;
+               TI_DbgPrint(DEBUG_TCP,
+                           ("Completing Request %x\n", Bucket->Request.RequestContext));
+
+               Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 );
+
+               /* Frees the bucket allocated in TCPConnect */
+               exFreePool( Bucket );
+           }
+           KeAcquireSpinLock(&Connection->Lock, &OldIrql);
+       }
+
+       if( Connection->SignalState & SEL_ACCEPT ) {
+           /* Handle readable on a listening socket --
+            * TODO: Implement filtering
+            */
+
+           KeReleaseSpinLock(&Connection->Lock, OldIrql);
+
+           TI_DbgPrint(DEBUG_TCP,("Accepting new connection on %x (Queue: %s)\n",
+                                  Connection,
+                                  IsListEmpty(&Connection->ListenRequest) ?
+                                  "empty" : "nonempty"));
+
+           while( (Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest,
+                                                        &Connection->Lock )) != NULL ) {
+               PIO_STACK_LOCATION IrpSp;
+
+               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+               Complete = Bucket->Request.RequestNotifyObject;
+
+               Irp = Bucket->Request.RequestContext;
+               IrpSp = IoGetCurrentIrpStackLocation( Irp );
+
+               TI_DbgPrint(DEBUG_TCP,("Getting the socket\n"));
+
+               KeAcquireSpinLock(&Connection->Lock, &OldIrql);
+
+               Status = TCPServiceListeningSocket
+                   ( Connection->AddressFile->Listener,
+                     Bucket->AssociatedEndpoint,
+                     (PTDI_REQUEST_KERNEL)&IrpSp->Parameters );
+
+               KeReleaseSpinLock(&Connection->Lock, OldIrql);
+
+               TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n"));
+
+               if( Status == STATUS_PENDING ) {
+                   ExInterlockedInsertHeadList( &Connection->ListenRequest, &Bucket->Entry,
+                                                &Connection->Lock );
+                   break;
+               } else {
+                   Complete( Bucket->Request.RequestContext, Status, 0 );
+                   exFreePool( Bucket );
+               }
+          }
+
+          KeAcquireSpinLock(&Connection->Lock, &OldIrql);
+      }
+
+      /* Things that happen after we're connected */
+      if( Connection->SignalState & SEL_READ &&
+          Connection->SignalState & SEL_CONNECT ) {
+          TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n",
+                                 IsListEmpty(&Connection->ReceiveRequest) ?
+                                 "empty" : "nonempty"));
+
+          KeReleaseSpinLock(&Connection->Lock, OldIrql);
+
+           while( (Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest,
+                                                        &Connection->Lock )) != NULL ) {
+               OSK_UINT RecvLen = 0, Received = 0;
+               PVOID RecvBuffer = 0;
+
+               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+               Complete = Bucket->Request.RequestNotifyObject;
+
+               Irp = Bucket->Request.RequestContext;
+               Mdl = Irp->MdlAddress;
+
+               TI_DbgPrint(DEBUG_TCP,
+                           ("Getting the user buffer from %x\n", Mdl));
+
+               NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen );
+
+               TI_DbgPrint(DEBUG_TCP,
+                           ("Reading %d bytes to %x\n", RecvLen, RecvBuffer));
+
+               TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
+               TI_DbgPrint
+                   (DEBUG_TCP,
+                    ("Connection->SocketContext: %x\n",
+                     Connection->SocketContext));
+               TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer));
+
+               KeAcquireSpinLock(&Connection->Lock, &OldIrql);
+
+               Status = TCPTranslateError
+                    ( OskitTCPRecv( Connection->SocketContext,
+                                    RecvBuffer,
+                                    RecvLen,
+                                    &Received,
+                                    0 ) );
+
+               KeReleaseSpinLock(&Connection->Lock, OldIrql);
+
+               TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received));
+
+               if( Status == STATUS_SUCCESS ) {
+                   TI_DbgPrint(DEBUG_TCP,("Received %d bytes with status %x\n",
+                                          Received, Status));
+                   Complete( Bucket->Request.RequestContext,
+                             STATUS_SUCCESS, Received );
+                   exFreePool( Bucket );
+               } else if( Status == STATUS_PENDING ) {
+                   ExInterlockedInsertHeadList( &Connection->ReceiveRequest, &Bucket->Entry,
+                                                &Connection->Lock );
+                   break;
+               } else {
+                   TI_DbgPrint(DEBUG_TCP,
+                               ("Completing Receive request: %x %x\n",
+                                Bucket->Request, Status));
+                   Complete( Bucket->Request.RequestContext, Status, 0 );
+                   exFreePool( Bucket );
+               }
+           }
+
+           KeAcquireSpinLock(&Connection->Lock, &OldIrql);
+       }
+       if( Connection->SignalState & SEL_WRITE &&
+           Connection->SignalState & SEL_CONNECT ) {
+           TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n",
+                                  IsListEmpty(&Connection->SendRequest) ?
+                                  "empty" : "nonempty"));
+
+           KeReleaseSpinLock(&Connection->Lock, OldIrql);
+
+           while( (Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest,
+                                                        &Connection->Lock )) != NULL ) {
+               OSK_UINT SendLen = 0, Sent = 0;
+               PVOID SendBuffer = 0;
+
+               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+               Complete = Bucket->Request.RequestNotifyObject;
+
+               Irp = Bucket->Request.RequestContext;
+               Mdl = Irp->MdlAddress;
+
+               TI_DbgPrint(DEBUG_TCP,
+                           ("Getting the user buffer from %x\n", Mdl));
+
+               NdisQueryBuffer( Mdl, &SendBuffer, &SendLen );
+
+               TI_DbgPrint(DEBUG_TCP,
+                           ("Writing %d bytes to %x\n", SendLen, SendBuffer));
+
+               TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
+               TI_DbgPrint
                 (DEBUG_TCP,
                  ("Connection->SocketContext: %x\n",
                   Connection->SocketContext));
-            TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer));
-
-            Status = TCPTranslateError
-                ( OskitTCPRecv( Connection->SocketContext,
-                                RecvBuffer,
-                                RecvLen,
-                                &Received,
-                                0 ) );
-
-            TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received));
-
-            if( Status == STATUS_SUCCESS ) {
-                TI_DbgPrint(DEBUG_TCP,("Received %d bytes with status %x\n",
-                                       Received, Status));
-
-                Complete( Bucket->Request.RequestContext,
-                          STATUS_SUCCESS, Received );
-                exFreePool( Bucket );
-            } else if( Status == STATUS_PENDING ) {
-                ExInterlockedInsertHeadList
-                    ( &Connection->ReceiveRequest, &Bucket->Entry, &Connection->Lock );
-                Connection->SignalState |= SEL_READ;
-                break;
-            } else {
-                TI_DbgPrint(DEBUG_TCP,
-                            ("Completing Receive request: %x %x\n",
-                             Bucket->Request, Status));
-                Complete( Bucket->Request.RequestContext, Status, 0 );
-                exFreePool( Bucket );
-            }
-        }
-    }
-    if( Connection->SignalState & SEL_WRITE ) {
-        TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n",
-                               IsListEmpty(&Connection->SendRequest) ?
-                               "empty" : "nonempty"));
-
-        Connection->SignalState &= ~SEL_WRITE;
-        while( (Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest,
-                                                     &Connection->Lock )) != NULL ) {
-            OSK_UINT SendLen = 0, Sent = 0;
-            PVOID SendBuffer = 0;
-
-            Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-            Complete = Bucket->Request.RequestNotifyObject;
-
-            Irp = Bucket->Request.RequestContext;
-            Mdl = Irp->MdlAddress;
-
-            TI_DbgPrint(DEBUG_TCP,
-                        ("Getting the user buffer from %x\n", Mdl));
-
-            NdisQueryBuffer( Mdl, &SendBuffer, &SendLen );
-
-            TI_DbgPrint(DEBUG_TCP,
-                        ("Writing %d bytes to %x\n", SendLen, SendBuffer));
-
-            TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
-            TI_DbgPrint
-                (DEBUG_TCP,
-                 ("Connection->SocketContext: %x\n",
-                  Connection->SocketContext));
-
-            Status = TCPTranslateError
-                ( OskitTCPSend( Connection->SocketContext,
-                                SendBuffer,
-                                SendLen,
-                                &Sent,
-                                0 ) );
-
-            TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent));
-
-            if( Status == STATUS_SUCCESS ) {
-                TI_DbgPrint(DEBUG_TCP,("Sent %d bytes with status %x\n",
+
+               KeAcquireSpinLock(&Connection->Lock, &OldIrql);
+
+               Status = TCPTranslateError
+                   ( OskitTCPSend( Connection->SocketContext,
+                                   SendBuffer,
+                                   SendLen,
+                                   &Sent,
+                                   0 ) );
+
+               KeReleaseSpinLock(&Connection->Lock, OldIrql);
+
+               TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent));
+
+               if( Status == STATUS_SUCCESS ) {
+                   TI_DbgPrint(DEBUG_TCP,("Sent %d bytes with status %x\n",
                                        Sent, Status));
-
-                Complete( Bucket->Request.RequestContext,
-                          STATUS_SUCCESS, Sent );
-                exFreePool( Bucket );
-            } else if( Status == STATUS_PENDING ) {
-                ExInterlockedInsertHeadList
-                    ( &Connection->SendRequest, &Bucket->Entry, &Connection->Lock );
-                Connection->SignalState |= SEL_WRITE;
-                break;
-            } else {
-                TI_DbgPrint(DEBUG_TCP,
-                            ("Completing Send request: %x %x\n",
-                             Bucket->Request, Status));
-                Complete( Bucket->Request.RequestContext, Status, 0 );
-                exFreePool( Bucket );
-            }
-        }
-    }
-
-    return Connection->SignalState;
-}
-
-static VOID DrainSignals() {
-    PCONNECTION_ENDPOINT Connection;
-    PLIST_ENTRY CurrentEntry, NextEntry;
-    ULONG NewState;
-    KIRQL OldIrql;
-
-    KeAcquireSpinLock(&SignalledConnectionsLock, &OldIrql);
-    CurrentEntry = SignalledConnectionsList.Flink;
-    while (CurrentEntry != &SignalledConnectionsList)
-    {
-        NextEntry = CurrentEntry->Flink;
-        Connection = CONTAINING_RECORD( CurrentEntry, CONNECTION_ENDPOINT,
-                                        SignalList );
-
-        KeReleaseSpinLock(&SignalledConnectionsLock, OldIrql);
-        NewState = HandleSignalledConnection(Connection);
-        KeAcquireSpinLock(&SignalledConnectionsLock, &OldIrql);
-
-        if (NewState == SEL_FIN || NewState == 0)
-        {
-            RemoveEntryList(CurrentEntry);
-        }
-
-        CurrentEntry = NextEntry;
-    }
-    KeReleaseSpinLock(&SignalledConnectionsLock, OldIrql);
+                   Complete( Bucket->Request.RequestContext,
+                             STATUS_SUCCESS, Sent );
+                   exFreePool( Bucket );
+               } else if( Status == STATUS_PENDING ) {
+                   ExInterlockedInsertHeadList( &Connection->SendRequest, &Bucket->Entry,
+                                                &Connection->Lock );
+                   break;
+               } else {
+                   TI_DbgPrint(DEBUG_TCP,
+                               ("Completing Send request: %x %x\n",
+                               Bucket->Request, Status));
+                   Complete( Bucket->Request.RequestContext, Status, 0 );
+                   exFreePool( Bucket );
+               }
+           }
+           KeAcquireSpinLock(&Connection->Lock, &OldIrql);
+       }
+
+       KeReleaseSpinLock(&Connection->Lock, OldIrql);
+
+       if (!Connection->SocketContext)
+       {
+           TCPFreeConnectionEndpoint(Connection);
+       }
+
+       CurrentEntry = NextEntry;
+
+       KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
+    }
+
+    KeReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
 }
 
 PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) {
@@ -314,7 +325,7 @@
     RtlZeroMemory(Connection, sizeof(CONNECTION_ENDPOINT));
 
     /* Initialize spin lock that protects the connection endpoint file object */
-    TcpipInitializeSpinLock(&Connection->Lock);
+    KeInitializeSpinLock(&Connection->Lock);
     InitializeListHead(&Connection->ConnectRequest);
     InitializeListHead(&Connection->ListenRequest);
     InitializeListHead(&Connection->ReceiveRequest);
@@ -323,19 +334,32 @@
     /* Save client context pointer */
     Connection->ClientContext = ClientContext;
 
+    /* Add connection endpoint to global list */
+    ExInterlockedInsertTailList(&ConnectionEndpointListHead,
+                                &Connection->ListEntry,
+                                &ConnectionEndpointListLock);
+
     return Connection;
 }
 
 VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection ) {
+    KIRQL OldIrql;
+
     TI_DbgPrint(DEBUG_TCP, ("Freeing TCP Endpoint\n"));
+
+    TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
+    RemoveEntryList(&Connection->ListEntry);
+    TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
+
     exFreePool( Connection );
 }
 
 NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection,
                     UINT Family, UINT Type, UINT Proto ) {
     NTSTATUS Status;
-
-    TcpipRecursiveMutexEnter(&TCPLock);
+    KIRQL OldIrql;
+
+    KeAcquireSpinLock(&Connection->Lock, &OldIrql);
 
     TI_DbgPrint(DEBUG_TCP,("Called: Connection %x, Family %d, Type %d, "
                            "Proto %d\n",
@@ -352,7 +376,7 @@
     TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n",
                            Connection->SocketContext));
 
-    TcpipRecursiveMutexLeave(&TCPLock);
+    KeReleaseSpinLock(&Connection->Lock, OldIrql);
 
     return Status;
 }
@@ -370,13 +394,9 @@
                            IPPacket->TotalSize,
                            IPPacket->HeaderSize));
 
-    TcpipRecursiveMutexEnter( &TCPLock );
-
     OskitTCPReceiveDatagram( IPPacket->Header,
                              IPPacket->TotalSize,
                              IPPacket->HeaderSize );
-
-    TcpipRecursiveMutexLeave( &TCPLock );
 }
 
 /* event.c */
@@ -447,10 +467,7 @@
             PsTerminateSystemThread(Status);
         }
 
-        TcpipRecursiveMutexEnter( &TCPLock );
         TimerOskitTCP( Next == NextFast, Next == NextSlow );
-        TcpipRecursiveMutexLeave( &TCPLock );
-
         if (Next == NextSlow) {
             DrainSignals();
         }
@@ -483,9 +500,6 @@
 {
     NTSTATUS Status;
 
-    TcpipRecursiveMutexInit( &TCPLock );
-    KeInitializeSpinLock( &SignalledConnectionsLock );
-    InitializeListHead( &SignalledConnectionsList );
     Status = TCPMemStartup();
     if ( ! NT_SUCCESS(Status) ) {
         return Status;
@@ -497,10 +511,8 @@
         return Status;
     }
 
-    TcpipRecursiveMutexEnter(&TCPLock);
     RegisterOskitTCPEventHandlers( &EventHandlers );
     InitOskitTCP();
-    TcpipRecursiveMutexLeave(&TCPLock);
 
     /* Register this protocol with IP layer */
     IPRegisterProtocol(IPPROTO_TCP, TCPReceive);
@@ -545,9 +557,7 @@
 
     TCPInitialized = FALSE;
 
-    TcpipRecursiveMutexEnter(&TCPLock);
     DeinitOskitTCP();
-    TcpipRecursiveMutexLeave(&TCPLock);
 
     PortsShutdown( &TCPPorts );
 
@@ -597,6 +607,7 @@
     USHORT RemotePort;
     PTDI_BUCKET Bucket;
     PNEIGHBOR_CACHE_ENTRY NCE;
+    KIRQL OldIrql;
 
     TI_DbgPrint(DEBUG_TCP,("TCPConnect: Called\n"));
 
@@ -625,7 +636,7 @@
     AddressToBind = AddressToConnect;
     AddressToBind.sin_addr.s_addr = NCE->Interface->Unicast.Address.IPv4Address;
 
-    TcpipRecursiveMutexEnter(&TCPLock);
+    KeAcquireSpinLock(&Connection->Lock, &OldIrql);
 
     Status = TCPTranslateError
         ( OskitTCPBind( Connection->SocketContext,
@@ -640,25 +651,28 @@
 
         Status = TCPTranslateError
             ( OskitTCPConnect( Connection->SocketContext,
-                               Connection,
                                &AddressToConnect,
                                sizeof(AddressToConnect) ) );
+
+        KeReleaseSpinLock(&Connection->Lock, OldIrql);
 
         if (Status == STATUS_PENDING)
         {
             Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) );
-            if( !Bucket ) return STATUS_NO_MEMORY;
+            if( !Bucket )
+            {
+               return STATUS_NO_MEMORY;
+            }
             
             Bucket->Request.RequestNotifyObject = (PVOID)Complete;
             Bucket->Request.RequestContext = Context;
-            
-            IoMarkIrpPending((PIRP)Context);
 			
-            ExInterlockedInsertTailList( &Connection->ConnectRequest, &Bucket->Entry, &Connection->Lock );
-        }
-    }
-
-    TcpipRecursiveMutexLeave(&TCPLock);
+            ExInterlockedInsertTailList( &Connection->ConnectRequest, &Bucket->Entry,
+                                         &Connection->Lock );
+        }
+    } else {
+        KeReleaseSpinLock(&Connection->Lock, OldIrql);
+    }
 
     return Status;
 }
@@ -671,12 +685,11 @@
   PTCP_COMPLETION_ROUTINE Complete,
   PVOID Context ) {
     NTSTATUS Status = STATUS_INVALID_PARAMETER;
-
-    ASSERT_LOCKED(&TCPLock);
+    KIRQL OldIrql;
 
     TI_DbgPrint(DEBUG_TCP,("started\n"));
 
-    TcpipRecursiveMutexEnter(&TCPLock);
+    KeAcquireSpinLock(&Connection->Lock, &OldIrql);
 
     if (Flags & TDI_DISCONNECT_RELEASE)
         Status = TCPTranslateError(OskitTCPDisconnect(Connection->SocketContext));
@@ -684,7 +697,7 @@
     if ((Flags & TDI_DISCONNECT_ABORT) || !Flags)
         Status = TCPTranslateError(OskitTCPShutdown(Connection->SocketContext, FWRITE | FREAD));
 
-    TcpipRecursiveMutexLeave(&TCPLock);
+    KeReleaseSpinLock(&Connection->Lock, OldIrql);
 
     TI_DbgPrint(DEBUG_TCP,("finished %x\n", Status));
 
@@ -694,20 +707,20 @@
 NTSTATUS TCPClose
 ( PCONNECTION_ENDPOINT Connection ) {
     NTSTATUS Status;
+    KIRQL OldIrql;
+    PVOID Socket;
 
     TI_DbgPrint(DEBUG_TCP,("TCPClose started\n"));
 
-    /* Make our code remove all pending IRPs */
-    Connection->SignalState |= SEL_FIN;
-    HandleSignalledConnection(Connection);
-
-    TcpipRecursiveMutexEnter(&TCPLock);
-
-    Status = TCPTranslateError( OskitTCPClose( Connection->SocketContext ) );
-    if (Status == STATUS_SUCCESS)
-        Connection->SocketContext = NULL;
-
-    TcpipRecursiveMutexLeave(&TCPLock);
+    KeAcquireSpinLock(&Connection->Lock, &OldIrql);
+    Socket = Connection->SocketContext;
+    Connection->SocketContext = NULL;
+    Status = TCPTranslateError( OskitTCPClose( Socket ) );
+    if (!NT_SUCCESS(Status))
+    {
+        Connection->SocketContext = Socket;
+    }
+    KeReleaseSpinLock(&Connection->Lock, OldIrql);
 
     TI_DbgPrint(DEBUG_TCP,("TCPClose finished %x\n", Status));
 
@@ -726,17 +739,18 @@
     UINT DataLen, Received = 0;
     NTSTATUS Status;
     PTDI_BUCKET Bucket;
+    KIRQL OldIrql;
 
     TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n",
                            ReceiveLength, Connection->SocketContext));
 
+    NdisQueryBuffer( Buffer, &DataBuffer, &DataLen );
+
+    TI_DbgPrint(DEBUG_TCP,("TCP>|< Got an MDL %x (%x:%d)\n", Buffer, DataBuffer, DataLen));
+
+    KeAcquireSpinLock(&Connection->Lock, &OldIrql);
+
     ASSERT_KM_POINTER(Connection->SocketContext);
-
-    NdisQueryBuffer( Buffer, &DataBuffer, &DataLen );
-
-    TI_DbgPrint(DEBUG_TCP,("TCP>|< Got an MDL %x (%x:%d)\n", Buffer, DataBuffer, DataLen));
-
-    TcpipRecursiveMutexEnter(&TCPLock);
 
     Status = TCPTranslateError
         ( OskitTCPRecv
@@ -746,7 +760,7 @@
             &Received,
             ReceiveFlags ) );
 
-    TcpipRecursiveMutexLeave(&TCPLock);
+    KeReleaseSpinLock(&Connection->Lock, OldIrql);
 
     TI_DbgPrint(DEBUG_TCP,("OskitTCPReceive: %x, %d\n", Status, Received));
 
@@ -763,9 +777,8 @@
         Bucket->Request.RequestContext = Context;
         *BytesReceived = 0;
 
-        IoMarkIrpPending((PIRP)Context);
-
-        ExInterlockedInsertTailList( &Connection->ReceiveRequest, &Bucket->Entry, &Connection->Lock );
+        ExInterlockedInsertTailList( &Connection->ReceiveRequest, &Bucket->Entry,
+                                     &Connection->Lock );
         TI_DbgPrint(DEBUG_TCP,("Queued read irp\n"));
     } else {
         TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Received));
@@ -788,8 +801,9 @@
     UINT Sent = 0;
     NTSTATUS Status;
     PTDI_BUCKET Bucket;
-
-    ASSERT_LOCKED(&TCPLock);
+    KIRQL OldIrql;
+
+    KeAcquireSpinLock(&Connection->Lock, &OldIrql);
 
     TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n",
                            SendLength, Connection->SocketContext));
@@ -799,15 +813,13 @@
     TI_DbgPrint(DEBUG_TCP,("Connection = %x\n", Connection));
     TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext = %x\n",
                            Connection->SocketContext));
-
-    TcpipRecursiveMutexEnter(&TCPLock);
 
     Status = TCPTranslateError
         ( OskitTCPSend( Connection->SocketContext,
                         (OSK_PCHAR)BufferData, SendLength,
                         &Sent, 0 ) );
 
-    TcpipRecursiveMutexLeave(&TCPLock);
+    KeReleaseSpinLock(&Connection->Lock, OldIrql);
 
     TI_DbgPrint(DEBUG_TCP,("OskitTCPSend: %x, %d\n", Status, Sent));
 
@@ -823,10 +835,9 @@
         Bucket->Request.RequestNotifyObject = Complete;
         Bucket->Request.RequestContext = Context;
         *BytesSent = 0;
-
-        IoMarkIrpPending((PIRP)Context);
         
-        ExInterlockedInsertTailList( &Connection->SendRequest, &Bucket->Entry, &Connection->Lock );
+        ExInterlockedInsertTailList( &Connection->SendRequest, &Bucket->Entry,
+                                     &Connection->Lock );
         TI_DbgPrint(DEBUG_TCP,("Queued write irp\n"));
     } else {
         TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Sent));
@@ -865,14 +876,15 @@
     OSK_UI16 LocalPort, RemotePort;
     PTA_IP_ADDRESS AddressIP = (PTA_IP_ADDRESS)Address;
     NTSTATUS Status;
-
-    TcpipRecursiveMutexEnter(&TCPLock);
+    KIRQL OldIrql;
+
+    KeAcquireSpinLock(&Connection->Lock, &OldIrql);
 
     Status = TCPTranslateError(OskitTCPGetAddress(Connection->SocketContext,
                                                   &LocalAddress, &LocalPort,
                                                   &RemoteAddress, &RemotePort));
 
-    TcpipRecursiveMutexLeave(&TCPLock);
+    KeReleaseSpinLock(&Connection->Lock, OldIrql);
 
     if (!NT_SUCCESS(Status))
         return Status;

Modified: trunk/reactos/lib/drivers/ip/transport/udp/udp.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/transport/udp/udp.c?rev=44163&r1=44162&r2=44163&view=diff
==============================================================================
--- trunk/reactos/lib/drivers/ip/transport/udp/udp.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/ip/transport/udp/udp.c [iso-8859-1] Sat Nov 14 19:38:02 2009
@@ -172,6 +172,9 @@
     USHORT RemotePort;
     NTSTATUS Status;
     PNEIGHBOR_CACHE_ENTRY NCE;
+    KIRQL OldIrql;
+
+    KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
 
     TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n",
 						   AddrFile, ConnInfo, BufferData, DataSize));
@@ -186,10 +189,12 @@
 		break;
 
     default:
+		KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
 		return STATUS_UNSUCCESSFUL;
     }
 
     if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) {
+		KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
 		return STATUS_NETWORK_UNREACHABLE;
     }
 
@@ -213,13 +218,19 @@
 							 DataSize );
 
     if( !NT_SUCCESS(Status) )
+    {
+		KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
 		return Status;
+    }
 
     if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, UDPSendPacketComplete, NULL )))
     {
+	KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
         FreeNdisPacket(Packet.NdisPacket);
         return Status;
     }
+
+    KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
 
     return STATUS_SUCCESS;
 }

Modified: trunk/reactos/lib/drivers/oskittcp/include/oskittcp.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/oskittcp/include/oskittcp.h?rev=44163&r1=44162&r2=44163&view=diff
==============================================================================
--- trunk/reactos/lib/drivers/oskittcp/include/oskittcp.h [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/oskittcp/include/oskittcp.h [iso-8859-1] Sat Nov 14 19:38:02 2009
@@ -123,7 +123,7 @@
 			 OSK_UINT *OutLen,
 			 OSK_UINT Flags );
 
-extern int OskitTCPConnect( void *socket, void *connection,
+extern int OskitTCPConnect( void *socket,
 			    void *nam, OSK_UINT namelen );
 extern int OskitTCPClose( void *socket );
 
@@ -131,7 +131,7 @@
 			 void *nam, OSK_UINT namelen );
 
 extern int OskitTCPAccept( void *socket, void **new_socket,
-			   void *addr_out,
+			   void *context, void *addr_out,
 			   OSK_UINT addr_len,
 			   OSK_UINT *out_addr_len,
 			   OSK_UINT finish_accept );
@@ -187,4 +187,27 @@
 #define	FREAD		0x0001
 #define	FWRITE		0x0002
 
+/* Don't define this unless your are insane or aicom */
+//#define LOCK_SPAM
+
+#ifdef LOCK_SPAM
+#define OSKLock() if (!KeTryToAcquireSpinLockAtDpcLevel(&OSKLock)) \
+                  { \
+                      DbgPrint("OSKLock WAIT (%s)\n", __FUNCTION__); \
+                      KeAcquireSpinLockAtDpcLevel(&OSKLock); \
+                  } \
+                  DbgPrint("OSKLock >>>> (%s)\n", __FUNCTION__)
+
+#define OSKUnlock() KeReleaseSpinLockFromDpcLevel(&OSKLock); \
+                    DbgPrint("OSKLock <<<< (%s)\n", __FUNCTION__)
+#else
+#define OSKLock() KeAcquireSpinLockAtDpcLevel(&OSKLock)
+#define OSKUnlock() KeReleaseSpinLockFromDpcLevel(&OSKLock)
+#endif
+
+#define OSKLockAndRaise(x) KeRaiseIrql(DISPATCH_LEVEL, x); \
+                           OSKLock()
+#define OSKUnlockAndLower(x) OSKUnlock(); \
+                             KeLowerIrql(x)
+
 #endif/*OSKITTCP_H*/

Modified: trunk/reactos/lib/drivers/oskittcp/oskittcp/interface.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/oskittcp/oskittcp/interface.c?rev=44163&r1=44162&r2=44163&view=diff
==============================================================================
--- trunk/reactos/lib/drivers/oskittcp/oskittcp/interface.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/oskittcp/oskittcp/interface.c [iso-8859-1] Sat Nov 14 19:38:02 2009
@@ -23,6 +23,8 @@
 //OSK_UINT OskitDebugTraceLevel = OSK_DEBUG_ULTRA;
 OSK_UINT OskitDebugTraceLevel = 0;
 
+KSPIN_LOCK OSKLock;
+
 /* SPL */
 unsigned cpl;
 unsigned net_imask;
@@ -45,6 +47,7 @@
 
 void InitOskitTCP() {
     OS_DbgPrint(OSK_MID_TRACE,("Init Called\n"));
+    KeInitializeSpinLock(&OSKLock);
     OS_DbgPrint(OSK_MID_TRACE,("MB Init\n"));
     mbinit();
     OS_DbgPrint(OSK_MID_TRACE,("Rawip Init\n"));
@@ -66,12 +69,19 @@
 }
 
 void TimerOskitTCP( int FastTimer, int SlowTimer ) {
+    KIRQL OldIrql;
+
+    /* This function is a special case in which we cannot use OSKLock/OSKUnlock 
+     * because we don't enter with the connection lock held */
+
+    OSKLockAndRaise(&OldIrql);
     if ( SlowTimer ) {
         tcp_slowtimo();
     }
     if ( FastTimer ) {
         tcp_fasttimo();
     }
+    OSKUnlockAndLower(OldIrql);
 }
 
 void RegisterOskitTCPEventHandlers( POSKITTCP_EVENT_HANDLERS EventHandlers ) {
@@ -115,12 +125,16 @@
 		    int proto )
 {
     struct socket *so;
+
+    OSKLock();
     int error = socreate(domain, &so, type, proto);
     if( !error ) {
 	so->so_connection = context;
 	so->so_state |= SS_NBIO;
 	*aso = so;
     }
+    OSKUnlock();
+
     return error;
 }
 
@@ -153,8 +167,11 @@
 
     OS_DbgPrint(OSK_MID_TRACE,("Reading %d bytes from TCP:\n", Len));
 
+    OSKLock();
     error = soreceive( connection, NULL, &uio, NULL, NULL /* SCM_RIGHTS */,
 		       &tcp_flags );
+    OSKUnlock();
+
     *OutLen = Len - uio.uio_resid;
 
     return error;
@@ -182,14 +199,15 @@
     addr.sa_family = addr.sa_len;
     addr.sa_len = sizeof(struct sockaddr);
 
+    OSKLock();
     error = sobind(so, &sabuf);
+    OSKUnlock();
 
     OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error));
     return (error);
 }
 
-int OskitTCPConnect( void *socket, void *connection,
-		     void *nam, OSK_UINT namelen ) {
+int OskitTCPConnect( void *socket, void *nam, OSK_UINT namelen ) {
     struct socket *so = socket;
     int error = EFAULT;
     struct mbuf sabuf;
@@ -197,8 +215,7 @@
 
     OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", socket));
 
-    so->so_connection = connection;
-
+    OSKLock();
     if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
 	error = EALREADY;
 	goto done;
@@ -217,7 +234,9 @@
 
     error = soconnect(so, &sabuf);
 
-    if (error)
+    if (error == EINPROGRESS)
+        goto done;
+    else if (error)
 	goto bad;
 
     if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
@@ -232,34 +251,49 @@
 	error = EINTR;
 
 done:
+    OSKUnlock();
     OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error));
     return (error);
 }
 
 int OskitTCPDisconnect(void *socket)
 {
-    if (!socket)
-        return OSK_ESHUTDOWN;
-
-    return sodisconnect(socket);
+    int error;
+
+    if (!socket)
+        return OSK_ESHUTDOWN;
+
+    OSKLock();
+    error = sodisconnect(socket);
+    OSKUnlock();
+
+    return error;
 }
 
 int OskitTCPShutdown( void *socket, int disconn_type ) {
-    if (!socket)
-        return OSK_ESHUTDOWN;
-
-    return soshutdown( socket, disconn_type );
+    int error;
+
+    if (!socket)
+        return OSK_ESHUTDOWN;
+
+    OSKLock();
+    error = soshutdown( socket, disconn_type );
+    OSKUnlock();
+
+    return error;
 }
 
 int OskitTCPClose( void *socket ) {
-    struct socket *so = socket;
-
-    if (!socket)
-        return OSK_ESHUTDOWN;
-
-    so->so_connection = 0;
-    soclose( so );
-    return 0;
+    int error;
+
+    if (!socket)
+        return OSK_ESHUTDOWN;
+
+    OSKLock();
+    error = soclose( socket );
+    OSKUnlock();
+
+    return error;
 }
 
 int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len,
@@ -281,7 +315,10 @@
     uio.uio_rw = UIO_WRITE;
     uio.uio_procp = NULL;
 
+    OSKLock();
     error = sosend( socket, NULL, &uio, NULL, NULL, 0 );
+    OSKUnlock();
+
     *OutLen = Len - uio.uio_resid;
 
     return error;
@@ -289,6 +326,7 @@
 
 int OskitTCPAccept( void *socket,
 		    void **new_socket,
+		    void *context,
 		    void *AddrOut,
 		    OSK_UINT AddrLen,
 		    OSK_UINT *OutAddrLen,
@@ -317,11 +355,12 @@
 	/* that's a copyin actually */
 	namelen = *OutAddrLen;
 
+    OSKLock();
+
     s = splnet();
 
 #if 0
     if ((head->so_options & SO_ACCEPTCONN) == 0) {
-	splx(s);
 	OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: head->so_options = %x, wanted bit %x\n",
 				   head->so_options, SO_ACCEPTCONN));
 	error = EINVAL;
@@ -333,38 +372,9 @@
 			       head->so_q, head->so_state));
 
     if ((head->so_state & SS_NBIO) && head->so_q == NULL) {
-	splx(s);
 	error = EWOULDBLOCK;
 	goto out;
     }
-
-    OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
-    while (head->so_q == NULL && head->so_error == 0) {
-	if (head->so_state & SS_CANTRCVMORE) {
-	    head->so_error = ECONNABORTED;
-	    break;
-	}
-	OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
-	error = tsleep((caddr_t)&head->so_timeo, PSOCK | PCATCH,
-		       "accept", 0);
-	if (error) {
-	    splx(s);
-	    goto out;
-	}
-	OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
-    }
-    OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
-
-#if 0
-    if (head->so_error) {
-	OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
-	error = head->so_error;
-	head->so_error = 0;
-	splx(s);
-	goto out;
-    }
-    OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
-#endif
 
     /*
      * At this point we know that there is at least one connection
@@ -384,19 +394,20 @@
 	head->so_q = so->so_q;
 	head->so_qlen--;
 
-	*newso = so;
-
-	/*so->so_state &= ~SS_COMP;*/
-
 	mnam.m_data = (char *)&sa;
 	mnam.m_len = sizeof(sa);
 
-	(void) soaccept(so, &mnam);
-
-	so->so_state = SS_NBIO | SS_ISCONNECTED;
+	error = soaccept(so, &mnam);
+        if (error)
+            goto out;
+
+	so->so_state |= SS_NBIO | SS_ISCONNECTED;
         so->so_q = so->so_q0 = NULL;
         so->so_qlen = 0;
         so->so_head = 0;
+        so->so_connection = context;
+
+	*newso = so;
 
 	OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
 	if (name) {
@@ -406,9 +417,10 @@
 	    *OutAddrLen = namelen;	/* copyout actually */
 	}
 	OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
-	splx(s);
     }
 out:
+    splx(s);
+    OSKUnlock();
     OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: Returning %d\n", error));
     return (error);
 }
@@ -421,10 +433,20 @@
 
 void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len,
 			      OSK_UINT IpHeaderLen ) {
-    struct mbuf *Ip = m_devget( (char *)Data, Len, 0, NULL, NULL );
+    struct mbuf *Ip;
     struct ip *iph;
-
-    if( !Ip ) return; /* drop the segment */
+    KIRQL OldIrql;
+
+    /* This function is a special case in which we cannot use OSKLock/OSKUnlock 
+     * because we don't enter with the connection lock held */
+
+    OSKLockAndRaise(&OldIrql);
+    Ip = m_devget( (char *)Data, Len, 0, NULL, NULL );
+    if( !Ip )
+    {
+       OSKUnlockAndLower(OldIrql);
+       return; /* drop the segment */
+    }
 
     //memcpy( Ip->m_data, Data, Len );
     Ip->m_pkthdr.len = IpHeaderLen;
@@ -439,6 +461,7 @@
 		 IpHeaderLen));
 
     tcp_input(Ip, IpHeaderLen);
+    OSKUnlockAndLower(OldIrql);
 
     /* The buffer Ip is freed by tcp_input */
 }
@@ -450,6 +473,7 @@
                        int size)
 {
     struct mbuf *m;
+    int error;
 
     if (!socket)
         return OSK_ESHUTDOWN;
@@ -457,16 +481,23 @@
     if (size >= MLEN)
         return OSK_EINVAL;
 
+    OSKLock();
     m = m_get(M_WAIT, MT_SOOPTS);
     if (!m)
+    {
+        OSKUnlock();
         return OSK_ENOMEM;
+    }
 
     m->m_len = size;
 
     memcpy(m->m_data, buffer, size);
 
     /* m is freed by sosetopt */
-    return sosetopt(socket, level, optname, m);
+    error = sosetopt(socket, level, optname, m);
+    OSKUnlock();
+
+    return error;
 }   
 
 int OskitTCPGetSockOpt(void *socket,
@@ -481,6 +512,7 @@
     if (!socket)
         return OSK_ESHUTDOWN;
 
+    OSKLock();
     error = sogetopt(socket, level, optname, &m);
     if (!error)
     {
@@ -489,6 +521,7 @@
         if (!buffer || oldsize < m->m_len)
         {
             m_freem(m);
+            OSKUnlock();
             return OSK_EINVAL;
         }
 
@@ -496,6 +529,7 @@
 
         m_freem(m);
     }
+    OSKUnlock();
 
     return error;
 }
@@ -507,7 +541,11 @@
         return OSK_ESHUTDOWN;
 
     OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", socket));
+
+    OSKLock();
     error = solisten( socket, backlog );
+    OSKUnlock();
+
     OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error));
 
     return error;
@@ -524,11 +562,13 @@
     if (!socket)
         return OSK_ESHUTDOWN;
 
+    OSKLock();
     inp = (struct inpcb *)so->so_pcb;
     inp->inp_laddr.s_addr = LocalAddress;
     inp->inp_lport = LocalPort;
     inp->inp_faddr.s_addr = RemoteAddress;
     inp->inp_fport = RemotePort;
+    OSKUnlock();
 
     return 0;
 }
@@ -544,11 +584,13 @@
     if (!socket)
         return OSK_ESHUTDOWN;
 
+    OSKLock();
     inp = (struct inpcb *)so->so_pcb;
     *LocalAddress = inp->inp_laddr.s_addr;
     *LocalPort = inp->inp_lport;
     *RemoteAddress = inp->inp_faddr.s_addr;
     *RemotePort = inp->inp_fport;
+    OSKUnlock();
 
     return 0;
 }




More information about the Ros-diffs mailing list