Fix deadlock when two threads were trying to SendMessage() each other
authorGé van Geldorp <ge@gse.nl>
Mon, 29 Dec 2003 10:09:33 +0000 (10:09 +0000)
committerGé van Geldorp <ge@gse.nl>
Mon, 29 Dec 2003 10:09:33 +0000 (10:09 +0000)
svn path=/trunk/; revision=7306

reactos/subsys/win32k/include/msgqueue.h
reactos/subsys/win32k/ntuser/message.c
reactos/subsys/win32k/ntuser/msgqueue.c

index 6a1e0f5..3348106 100644 (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);
index 0bd3c29..df19b81 100644 (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;
     }
 }
 
index 86bbba1..b89bb11 100644 (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