implemented sweeping of handle tables
[reactos.git] / reactos / ntoskrnl / lpc / close.c
index 272c696..1091bfc 100644 (file)
@@ -1,21 +1,16 @@
-/* $Id: close.c,v 1.7 2001/12/02 23:34:42 dwelch Exp $
- * 
+/* $Id$
+ *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/lpc/close.c
  * PURPOSE:         Communication mechanism
- * PROGRAMMER:      David Welch (welch@cwcom.net)
- * UPDATE HISTORY:
- *                  Created 22/05/98
+ *
+ * PROGRAMMERS:     David Welch (welch@cwcom.net)
  */
 
 /* INCLUDES *****************************************************************/
 
-#include <ddk/ntddk.h>
-#include <internal/ob.h>
-#include <internal/port.h>
-#include <internal/dbg.h>
-
+#include <ntoskrnl.h>
 #define NDEBUG
 #include <internal/debug.h>
 
  * RETURN VALUE
  *
  * REVISIONS
- *
  */
 VOID STDCALL
-NiClosePort (PVOID     ObjectBody, ULONG       HandleCount)
+LpcpClosePort (PVOID   ObjectBody, ULONG       HandleCount)
 {
   PEPORT Port = (PEPORT)ObjectBody;
-  LPC_MESSAGE Message;
-  
+  PORT_MESSAGE Message;
+
+  /* FIXME Race conditions here! */
+
+  DPRINT("NiClosePort 0x%p OtherPort 0x%p State %d\n", Port, Port->OtherPort, Port->State);
+
   /*
    * If the client has just closed its handle then tell the server what
    * happened and disconnect this port.
    */
-  if (HandleCount == 0 && Port->State == EPORT_CONNECTED_CLIENT && 
-      ObGetReferenceCount(Port) == 2)
+  if (HandleCount == 1 && Port->State == EPORT_CONNECTED_CLIENT)
     {
-      Message.MessageSize = sizeof(LPC_MESSAGE);
-      Message.DataSize = 0;
+      DPRINT("Informing server\n");
+      Message.u1.s1.TotalLength = sizeof(PORT_MESSAGE);
+      Message.u1.s1.DataLength = 0;
       EiReplyOrRequestPort (Port->OtherPort,
                            &Message,
                            LPC_PORT_CLOSED,
@@ -65,9 +63,9 @@ NiClosePort (PVOID    ObjectBody, ULONG       HandleCount)
    * If the server has closed all of its handles then disconnect the port,
    * don't actually notify the client until it attempts an operation.
    */
-  if (HandleCount == 0 && Port->State == EPORT_CONNECTED_SERVER && 
-      ObGetReferenceCount(Port) == 2)
+  if (HandleCount == 1 && Port->State == EPORT_CONNECTED_SERVER)
     {
+        DPRINT("Cleaning up server\n");
        Port->OtherPort->OtherPort = NULL;
        Port->OtherPort->State = EPORT_DISCONNECTED;
        ObDereferenceObject(Port->OtherPort);
@@ -85,14 +83,31 @@ NiClosePort (PVOID  ObjectBody, ULONG       HandleCount)
  * RETURN VALUE
  *
  * REVISIONS
- *
  */
 VOID STDCALL
-NiDeletePort (PVOID    ObjectBody)
+LpcpDeletePort (PVOID  ObjectBody)
 {
-   //   PEPORT Port = (PEPORT)ObjectBody;
-   
-   //   DPRINT1("Deleting port %x\n", Port);
+   PLIST_ENTRY Entry;
+   PQUEUEDMESSAGE      Message;
+
+   PEPORT Port = (PEPORT)ObjectBody;
+
+   DPRINT("Deleting port %x\n", Port);
+
+   /* Free all waiting messages */
+   while (!IsListEmpty(&Port->QueueListHead))
+     {
+       Entry = RemoveHeadList(&Port->QueueListHead);
+       Message = CONTAINING_RECORD (Entry, QUEUEDMESSAGE, QueueListEntry);
+       ExFreePool(Message);
+     }
+
+   while (!IsListEmpty(&Port->ConnectQueueListHead))
+     {
+       Entry = RemoveHeadList(&Port->ConnectQueueListHead);
+       Message = CONTAINING_RECORD (Entry, QUEUEDMESSAGE, QueueListEntry);
+       ExFreePool(Message);
+     }
 }