mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 20:03:12 +00:00
Fix deadlock when two threads were trying to SendMessage() each other
svn path=/trunk/; revision=7306
This commit is contained in:
parent
ea561a262b
commit
46376679ce
3 changed files with 45 additions and 36 deletions
|
@ -92,9 +92,9 @@ typedef struct _USER_MESSAGE_QUEUE
|
||||||
|
|
||||||
} USER_MESSAGE_QUEUE, *PUSER_MESSAGE_QUEUE;
|
} USER_MESSAGE_QUEUE, *PUSER_MESSAGE_QUEUE;
|
||||||
|
|
||||||
VOID FASTCALL
|
LRESULT FASTCALL
|
||||||
MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
|
MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
|
||||||
PUSER_SENT_MESSAGE Message);
|
HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam);
|
||||||
VOID FASTCALL
|
VOID FASTCALL
|
||||||
MsqInitializeMessage(PUSER_MESSAGE Message,
|
MsqInitializeMessage(PUSER_MESSAGE Message,
|
||||||
LPMSG Msg);
|
LPMSG Msg);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -707,7 +707,6 @@ IntSendMessage(HWND hWnd,
|
||||||
LPARAM lParam)
|
LPARAM lParam)
|
||||||
{
|
{
|
||||||
LRESULT Result;
|
LRESULT Result;
|
||||||
NTSTATUS Status;
|
|
||||||
PWINDOW_OBJECT Window;
|
PWINDOW_OBJECT Window;
|
||||||
PMSGMEMORY MsgMemoryEntry;
|
PMSGMEMORY MsgMemoryEntry;
|
||||||
INT lParamBufferSize;
|
INT lParamBufferSize;
|
||||||
|
@ -767,37 +766,10 @@ IntSendMessage(HWND hWnd,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PUSER_SENT_MESSAGE Message;
|
Result = MsqSendMessage(Window->MessageQueue, hWnd, Msg, wParam, lParam);
|
||||||
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);
|
|
||||||
|
|
||||||
IntReleaseWindowObject(Window);
|
IntReleaseWindowObject(Window);
|
||||||
Status = KeWaitForSingleObject(CompletionEvent,
|
return Result;
|
||||||
UserRequest,
|
|
||||||
UserMode,
|
|
||||||
FALSE,
|
|
||||||
NULL);
|
|
||||||
if (Status == STATUS_WAIT_0)
|
|
||||||
{
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -50,6 +50,8 @@
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
|
#define TAG_MSGQ TAG('M', 'S', 'G', 'Q')
|
||||||
|
|
||||||
#define SYSTEM_MESSAGE_QUEUE_SIZE (256)
|
#define SYSTEM_MESSAGE_QUEUE_SIZE (256)
|
||||||
|
|
||||||
static MSG SystemMessageQueue[SYSTEM_MESSAGE_QUEUE_SIZE];
|
static MSG SystemMessageQueue[SYSTEM_MESSAGE_QUEUE_SIZE];
|
||||||
|
@ -788,14 +790,49 @@ MsqSendNotifyMessage(PUSER_MESSAGE_QUEUE MessageQueue,
|
||||||
ExReleaseFastMutex(&MessageQueue->Lock);
|
ExReleaseFastMutex(&MessageQueue->Lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FASTCALL
|
LRESULT FASTCALL
|
||||||
MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
|
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);
|
ExAcquireFastMutex(&MessageQueue->Lock);
|
||||||
InsertTailList(&MessageQueue->SentMessagesListHead, &Message->ListEntry);
|
InsertTailList(&MessageQueue->SentMessagesListHead, &Message->ListEntry);
|
||||||
KeSetEvent(&MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
|
||||||
ExReleaseFastMutex(&MessageQueue->Lock);
|
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
|
VOID FASTCALL
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue