Fix deadlock when two threads were trying to SendMessage() each other

svn path=/trunk/; revision=7306
This commit is contained in:
Gé van Geldorp 2003-12-29 10:09:33 +00:00
parent ea561a262b
commit 46376679ce
3 changed files with 45 additions and 36 deletions

View file

@ -92,9 +92,9 @@ typedef struct _USER_MESSAGE_QUEUE
} USER_MESSAGE_QUEUE, *PUSER_MESSAGE_QUEUE;
VOID FASTCALL
LRESULT FASTCALL
MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
PUSER_SENT_MESSAGE Message);
HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam);
VOID FASTCALL
MsqInitializeMessage(PUSER_MESSAGE Message,
LPMSG Msg);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: message.c,v 1.45 2003/12/28 14:21:03 weiden Exp $
/* $Id: message.c,v 1.46 2003/12/29 10:09:33 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -707,7 +707,6 @@ IntSendMessage(HWND hWnd,
LPARAM lParam)
{
LRESULT Result;
NTSTATUS Status;
PWINDOW_OBJECT Window;
PMSGMEMORY MsgMemoryEntry;
INT lParamBufferSize;
@ -767,37 +766,10 @@ IntSendMessage(HWND hWnd,
}
else
{
PUSER_SENT_MESSAGE Message;
PKEVENT CompletionEvent;
CompletionEvent = ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), TAG_MSG);
KeInitializeEvent(CompletionEvent, NotificationEvent, FALSE);
Message = ExAllocatePoolWithTag(NonPagedPool, sizeof(USER_SENT_MESSAGE), TAG_MSG);
Message->Msg.hwnd = hWnd;
Message->Msg.message = Msg;
Message->Msg.wParam = wParam;
Message->Msg.lParam = lParam;
Message->CompletionEvent = CompletionEvent;
Message->Result = &Result;
Message->CompletionQueue = NULL;
Message->CompletionCallback = NULL;
MsqSendMessage(Window->MessageQueue, Message);
Result = MsqSendMessage(Window->MessageQueue, hWnd, Msg, wParam, lParam);
IntReleaseWindowObject(Window);
Status = KeWaitForSingleObject(CompletionEvent,
UserRequest,
UserMode,
FALSE,
NULL);
if (Status == STATUS_WAIT_0)
{
return Result;
}
else
{
return FALSE;
}
return Result;
}
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: msgqueue.c,v 1.59 2003/12/28 10:27:51 weiden Exp $
/* $Id: msgqueue.c,v 1.60 2003/12/29 10:09:33 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -50,6 +50,8 @@
/* GLOBALS *******************************************************************/
#define TAG_MSGQ TAG('M', 'S', 'G', 'Q')
#define SYSTEM_MESSAGE_QUEUE_SIZE (256)
static MSG SystemMessageQueue[SYSTEM_MESSAGE_QUEUE_SIZE];
@ -788,14 +790,49 @@ MsqSendNotifyMessage(PUSER_MESSAGE_QUEUE MessageQueue,
ExReleaseFastMutex(&MessageQueue->Lock);
}
VOID FASTCALL
LRESULT FASTCALL
MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
PUSER_SENT_MESSAGE Message)
HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
PUSER_SENT_MESSAGE Message;
KEVENT CompletionEvent;
PVOID WaitObjects[2];
NTSTATUS WaitStatus;
LRESULT Result;
PUSER_MESSAGE_QUEUE ThreadQueue;
KeInitializeEvent(&CompletionEvent, NotificationEvent, FALSE);
Message = ExAllocatePoolWithTag(PagedPool, sizeof(USER_SENT_MESSAGE), TAG_MSGQ);
Message->Msg.hwnd = Wnd;
Message->Msg.message = Msg;
Message->Msg.wParam = wParam;
Message->Msg.lParam = lParam;
Message->CompletionEvent = &CompletionEvent;
Message->Result = &Result;
Message->CompletionQueue = NULL;
Message->CompletionCallback = NULL;
ExAcquireFastMutex(&MessageQueue->Lock);
InsertTailList(&MessageQueue->SentMessagesListHead, &Message->ListEntry);
KeSetEvent(&MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
ExReleaseFastMutex(&MessageQueue->Lock);
ThreadQueue = PsGetWin32Thread()->MessageQueue;
WaitObjects[1] = &ThreadQueue->NewMessages;
WaitObjects[0] = &CompletionEvent;
do
{
WaitStatus = KeWaitForMultipleObjects(2, WaitObjects, WaitAny, UserRequest,
UserMode, TRUE, NULL, NULL);
while (MsqDispatchOneSentMessage(ThreadQueue))
{
;
}
}
while (NT_SUCCESS(WaitStatus) && STATUS_WAIT_0 != WaitStatus);
return (STATUS_WAIT_0 == WaitStatus ? Result : -1);
}
VOID FASTCALL