typedef struct _EPORT
{
- KSPIN_LOCK Lock;
- KEVENT Event;
-
- ULONG State;
-
- struct _EPORT * OtherPort;
-
- ULONG QueueLength;
- LIST_ENTRY QueueListHead;
-
- ULONG ConnectQueueLength;
- LIST_ENTRY ConnectQueueListHead;
-
- ULONG MaxDataLength;
- ULONG MaxConnectInfoLength;
+ KSPIN_LOCK Lock;
+ KSEMAPHORE Semaphore;
+
+ ULONG State;
+
+ struct _EPORT * OtherPort;
+
+ ULONG QueueLength;
+ LIST_ENTRY QueueListHead;
+
+ ULONG ConnectQueueLength;
+ LIST_ENTRY ConnectQueueListHead;
+
+ ULONG MaxDataLength;
+ ULONG MaxConnectInfoLength;
} EPORT, * PEPORT;
-/* $Id: close.c,v 1.4 2001/03/13 16:25:54 dwelch Exp $
+/* $Id: close.c,v 1.5 2001/06/23 19:13:33 phreak Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
{
Message.MessageSize = sizeof(LPC_MESSAGE);
Message.DataSize = 0;
-
EiReplyOrRequestPort (Port->OtherPort,
&Message,
LPC_PORT_CLOSED,
Port);
- KeSetEvent (&Port->OtherPort->Event,
- IO_NO_INCREMENT,
- FALSE);
-
Port->OtherPort->OtherPort = NULL;
Port->OtherPort->State = EPORT_DISCONNECTED;
+ KeReleaseSemaphore( &Port->OtherPort->Semaphore,
+ IO_NO_INCREMENT,
+ 1,
+ FALSE );
ObDereferenceObject (Port);
}
-/* $Id: complete.c,v 1.3 2001/01/18 15:00:08 dwelch Exp $
+/* $Id: complete.c,v 1.4 2001/06/23 19:13:33 phreak Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
return (Status);
}
- KeSetEvent (&OurPort->OtherPort->Event, IO_NO_INCREMENT, FALSE);
-
OurPort->State = EPORT_CONNECTED_SERVER;
+ KeReleaseSemaphore( &OurPort->OtherPort->Semaphore, IO_NO_INCREMENT, 1, FALSE );
+
ObDereferenceObject (OurPort);
return (STATUS_SUCCESS);
-/* $Id: connect.c,v 1.6 2001/06/16 14:08:57 ekohl Exp $
+/* $Id: connect.c,v 1.7 2001/06/23 19:13:33 phreak Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
Request,
LPC_CONNECTION_REQUEST,
OurPort);
- KeSetEvent (&NamedPort->Event, IO_NO_INCREMENT, FALSE);
+ KeReleaseSemaphore( &NamedPort->Semaphore, IO_NO_INCREMENT, 1, FALSE );
DPRINT("Waiting for connection completion\n");
/*
* Wait for them to accept our connection
*/
- KeWaitForSingleObject (&OurPort->Event,
+ KeWaitForSingleObject (&OurPort->Semaphore,
UserRequest,
UserMode,
FALSE,
LpcMessage,
LPC_CONNECTION_REFUSED,
NamedPort);
- KeSetEvent (&ConnectionRequest->Sender->Event,
- IO_NO_INCREMENT,
- FALSE);
+ KeReleaseSemaphore( &ConnectionRequest->Sender->Semaphore,
+ IO_NO_INCREMENT,
+ 1,
+ FALSE);
ObDereferenceObject (ConnectionRequest->Sender);
ExFreePool (ConnectionRequest);
ObDereferenceObject (NamedPort);
-/* $Id: port.c,v 1.5 2001/03/07 16:48:43 dwelch Exp $
+/* $Id: port.c,v 1.6 2001/06/23 19:13:33 phreak Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
{
memset (Port, 0, sizeof(EPORT));
KeInitializeSpinLock (& Port->Lock);
- KeInitializeEvent (& Port->Event, SynchronizationEvent, FALSE);
+ KeInitializeSemaphore( &Port->Semaphore, 0, LONG_MAX );
Port->OtherPort = NULL;
Port->QueueLength = 0;
Port->ConnectQueueLength = 0;
-/* $Id: reply.c,v 1.6 2001/03/07 16:48:43 dwelch Exp $
+/* $Id: reply.c,v 1.7 2001/06/23 19:13:33 phreak Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
LpcReply,
LPC_REPLY,
Port);
- KeSetEvent(&Port->OtherPort->Event, IO_NO_INCREMENT, FALSE);
+ KeReleaseSemaphore( &Port->OtherPort->Semaphore, IO_NO_INCREMENT, 1, FALSE );
ObDereferenceObject(Port);
PEPORT Port;
KIRQL oldIrql;
PQUEUEDMESSAGE Request;
+ BOOLEAN Disconnected;
+ LARGE_INTEGER to;
DPRINT("NtReplyWaitReceivePortEx(PortHandle %x, LpcReply %x, "
"LpcMessage %x)\n", PortHandle, LpcReply, LpcMessage);
DPRINT1("NtReplyWaitReceivePortEx() = %x\n", Status);
return(Status);
}
-
- if (Port->State != EPORT_CONNECTED_CLIENT &&
- Port->State != EPORT_CONNECTED_SERVER &&
- LpcReply != NULL)
+ if( Port->State == EPORT_DISCONNECTED )
{
- DPRINT1("NtReplyWaitReceivePortEx() = %x (State was %x)\n",
- STATUS_PORT_DISCONNECTED, Port->State);
- return(STATUS_PORT_DISCONNECTED);
+ // if the port is disconnected, force the timeout to be 0
+ // so we don't wait for new messages, because there won't be
+ // any, only try to remove any existing messages
+ Disconnected = TRUE;
+ to.QuadPart = 0;
+ Timeout = &to;
}
-
+ else Disconnected = FALSE;
+
/*
- * Send the reply
+ * Send the reply, only if port is connected
*/
- if (LpcReply != NULL)
+ if (LpcReply != NULL && !Disconnected)
{
Status = EiReplyOrRequestPort(Port->OtherPort,
LpcReply,
LPC_REPLY,
Port);
- KeSetEvent(&Port->OtherPort->Event, IO_NO_INCREMENT, FALSE);
+ KeReleaseSemaphore( &Port->OtherPort->Semaphore, IO_NO_INCREMENT, 1, FALSE);
if (!NT_SUCCESS(Status))
{
/*
* Want for a message to be received
*/
- do
+ Status = KeWaitForSingleObject(&Port->Semaphore,
+ UserRequest,
+ UserMode,
+ FALSE,
+ Timeout);
+ if( Status == STATUS_TIMEOUT )
{
- Status = KeWaitForSingleObject(&Port->Event,
- UserRequest,
- UserMode,
- FALSE,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtReplyWaitReceivePortEx() = %x\n", Status);
- return(Status);
- }
+ // if the port is disconnected, and there are no remaining messages,
+ // return STATUS_PORT_DISCONNECTED
+ ObDereferenceObject( Port );
+ return Disconnected ? STATUS_PORT_DISCONNECTED : STATUS_TIMEOUT;
+ }
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtReplyWaitReceivePortEx() = %x\n", Status);
+ ObDereferenceObject( Port );
+ return(Status);
+ }
- /*
- * Dequeue the message
- */
- KeAcquireSpinLock(&Port->Lock, &oldIrql);
- Request = EiDequeueMessagePort(Port);
-
- /*
- * There is a race between the event being set and the port lock being
- * taken in which another thread may dequeue the same request so
- * we may need to loop.
- */
- if (Request == NULL)
- {
- KeReleaseSpinLock(&Port->Lock, oldIrql);
- }
- } while(Request == NULL);
+ /*
+ * Dequeue the message
+ */
+ KeAcquireSpinLock(&Port->Lock, &oldIrql);
+ Request = EiDequeueMessagePort(Port);
+ assert( Request );
memcpy(LpcMessage, &Request->Message, Request->Message.MessageSize);
if (Request->Message.MessageType == LPC_CONNECTION_REQUEST)
{
-/* $Id: send.c,v 1.4 2001/03/18 19:35:13 dwelch Exp $
+/* $Id: send.c,v 1.5 2001/06/23 19:13:33 phreak Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
ObDereferenceObject(Port);
return(Status);
}
- KeSetEvent(&Port->OtherPort->Event, IO_NO_INCREMENT, FALSE);
+ KeReleaseSemaphore( &Port->OtherPort->Semaphore, IO_NO_INCREMENT, 1, FALSE );
/*
* Wait for a reply
*/
- KeWaitForSingleObject(&Port->Event,
+ KeWaitForSingleObject(&Port->Semaphore,
UserRequest,
UserMode,
FALSE,
LpcMessage,
LPC_DATAGRAM,
Port);
- KeSetEvent(&Port->Event, IO_NO_INCREMENT, FALSE);
+ KeReleaseSemaphore( &Port->Semaphore, IO_NO_INCREMENT, 1, FALSE );
return(Status);
}
ObDereferenceObject(Port);
return(Status);
}
- KeSetEvent(&Port->OtherPort->Event, IO_NO_INCREMENT, FALSE);
+ KeReleaseSemaphore( &Port->OtherPort->Semaphore, IO_NO_INCREMENT, 1, FALSE);
/*
* Wait for a reply
*/
- KeWaitForSingleObject(&Port->Event,
+ KeWaitForSingleObject(&Port->Semaphore,
UserRequest,
UserMode,
FALSE,