Move some profile stuff to NDK and fix some bugs in the executive implementation...
[reactos.git] / reactos / ntoskrnl / lpc / close.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/lpc/close.c
6 * PURPOSE: Communication mechanism
7 *
8 * PROGRAMMERS: David Welch (welch@cwcom.net)
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <internal/debug.h>
16
17 /* FUNCTIONS *****************************************************************/
18
19 /**********************************************************************
20 * NAME
21 *
22 * DESCRIPTION
23 *
24 * ARGUMENTS
25 *
26 * RETURN VALUE
27 *
28 * REVISIONS
29 */
30 VOID STDCALL
31 LpcpClosePort (PVOID ObjectBody, ULONG HandleCount)
32 {
33 PEPORT Port = (PEPORT)ObjectBody;
34 PORT_MESSAGE Message;
35
36 /* FIXME Race conditions here! */
37
38 DPRINT("NiClosePort 0x%p OtherPort 0x%p State %d\n", Port, Port->OtherPort, Port->State);
39
40 /*
41 * If the client has just closed its handle then tell the server what
42 * happened and disconnect this port.
43 */
44 if (HandleCount == 1 && Port->State == EPORT_CONNECTED_CLIENT)
45 {
46 DPRINT("Informing server\n");
47 Message.u1.s1.TotalLength = sizeof(PORT_MESSAGE);
48 Message.u1.s1.DataLength = 0;
49 EiReplyOrRequestPort (Port->OtherPort,
50 &Message,
51 LPC_PORT_CLOSED,
52 Port);
53 Port->OtherPort->OtherPort = NULL;
54 Port->OtherPort->State = EPORT_DISCONNECTED;
55 KeReleaseSemaphore( &Port->OtherPort->Semaphore,
56 IO_NO_INCREMENT,
57 1,
58 FALSE );
59 ObDereferenceObject (Port);
60 }
61
62 /*
63 * If the server has closed all of its handles then disconnect the port,
64 * don't actually notify the client until it attempts an operation.
65 */
66 if (HandleCount == 1 && Port->State == EPORT_CONNECTED_SERVER)
67 {
68 DPRINT("Cleaning up server\n");
69 Port->OtherPort->OtherPort = NULL;
70 Port->OtherPort->State = EPORT_DISCONNECTED;
71 ObDereferenceObject(Port->OtherPort);
72 }
73 }
74
75
76 /**********************************************************************
77 * NAME
78 *
79 * DESCRIPTION
80 *
81 * ARGUMENTS
82 *
83 * RETURN VALUE
84 *
85 * REVISIONS
86 */
87 VOID STDCALL
88 LpcpDeletePort (PVOID ObjectBody)
89 {
90 PLIST_ENTRY Entry;
91 PQUEUEDMESSAGE Message;
92
93 PEPORT Port = (PEPORT)ObjectBody;
94
95 DPRINT("Deleting port %x\n", Port);
96
97 /* Free all waiting messages */
98 while (!IsListEmpty(&Port->QueueListHead))
99 {
100 Entry = RemoveHeadList(&Port->QueueListHead);
101 Message = CONTAINING_RECORD (Entry, QUEUEDMESSAGE, QueueListEntry);
102 ExFreePool(Message);
103 }
104
105 while (!IsListEmpty(&Port->ConnectQueueListHead))
106 {
107 Entry = RemoveHeadList(&Port->ConnectQueueListHead);
108 Message = CONTAINING_RECORD (Entry, QUEUEDMESSAGE, QueueListEntry);
109 ExFreePool(Message);
110 }
111 }
112
113
114 /* EOF */