Commit in reactos/subsys/win32k on MAIN
include/msgqueue.h+5-21.38 -> 1.39
       /timer.h+3-31.5 -> 1.6
main/dllmain.c+2-21.76 -> 1.77
ntuser/caret.c+3-31.12 -> 1.13
      /msgqueue.c+45-391.100 -> 1.101
      /timer.c+26-371.33 -> 1.34
objects/text.c+3-21.107 -> 1.108
+87-88
7 modified files
attempt to fix a few message queue and timer bugs

reactos/subsys/win32k/include
msgqueue.h 1.38 -> 1.39
diff -u -r1.38 -r1.39
--- msgqueue.h	20 Jun 2004 16:27:14 -0000	1.38
+++ msgqueue.h	30 Jul 2004 09:16:06 -0000	1.39
@@ -17,17 +17,20 @@
 
 struct _USER_MESSAGE_QUEUE;
 
+#define USMF_WAKE_SENDER 0x1
+
 typedef struct _USER_SENT_MESSAGE
 {
   LIST_ENTRY ListEntry;
   MSG Msg;
-  PKEVENT CompletionEvent;
-  LRESULT* Result;
+  LRESULT Result;
+  ULONG Flags; /* the sender queue must be locked to access this field!!! */
   struct _USER_MESSAGE_QUEUE* SenderQueue;
   SENDASYNCPROC CompletionCallback;
   ULONG_PTR CompletionCallbackContext;
   /* entry in the dispatching list of the sender's message queue */
   LIST_ENTRY DispatchingListEntry;
+  KEVENT CompletionEvent;
 } USER_SENT_MESSAGE, *PUSER_SENT_MESSAGE;
 
 typedef struct _USER_SENT_MESSAGE_NOTIFY

reactos/subsys/win32k/include
timer.h 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- timer.h	31 Mar 2004 18:37:11 -0000	1.5
+++ timer.h	30 Jul 2004 09:16:06 -0000	1.6
@@ -4,15 +4,15 @@
 typedef struct _MSG_TIMER_ENTRY{
    LIST_ENTRY     ListEntry;
    LARGE_INTEGER  Timeout;
-   HANDLE          ThreadID;
+   struct _USER_MESSAGE_QUEUE* MessageQueue;
    UINT           Period;
    MSG            Msg;
 } MSG_TIMER_ENTRY, *PMSG_TIMER_ENTRY;
 
 NTSTATUS FASTCALL InitTimerImpl(VOID);
-VOID FASTCALL RemoveTimersThread(HANDLE ThreadID);
+VOID FASTCALL RemoveTimersThread(PUSER_MESSAGE_QUEUE MessageQueue);
 VOID FASTCALL RemoveTimersWindow(HWND hWnd);
-PMSG_TIMER_ENTRY FASTCALL IntRemoveTimer(HWND hWnd, UINT_PTR IDEvent, HANDLE ThreadID, BOOL SysTimer);
+PMSG_TIMER_ENTRY FASTCALL IntRemoveTimer(HWND hWnd, UINT_PTR IDEvent, BOOL SysTimer);
 UINT_PTR FASTCALL IntSetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc, BOOL SystemTimer);
 
 #endif /* _WIN32K_TIMER_H */

reactos/subsys/win32k/main
dllmain.c 1.76 -> 1.77
diff -u -r1.76 -r1.77
--- dllmain.c	22 May 2004 21:12:15 -0000	1.76
+++ dllmain.c	30 Jul 2004 09:16:06 -0000	1.77
@@ -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: dllmain.c,v 1.76 2004/05/22 21:12:15 weiden Exp $
+/* $Id: dllmain.c,v 1.77 2004/07/30 09:16:06 weiden Exp $
  *
  *  Entry Point for win32k.sys
  */
@@ -179,7 +179,7 @@
 
       Win32Thread->IsExiting = TRUE;
       HOOK_DestroyThreadHooks(Thread);
-      RemoveTimersThread(Thread->Cid.UniqueThread);
+      RemoveTimersThread(Win32Thread->MessageQueue);
       UnregisterThreadHotKeys(Thread);
       DestroyThreadWindows(Thread);
       IntBlockInput(Win32Thread, FALSE);

reactos/subsys/win32k/ntuser
caret.c 1.12 -> 1.13
diff -u -r1.12 -r1.13
--- caret.c	10 May 2004 17:07:18 -0000	1.12
+++ caret.c	30 Jul 2004 09:16:06 -0000	1.13
@@ -1,4 +1,4 @@
-/* $Id: caret.c,v 1.12 2004/05/10 17:07:18 weiden Exp $
+/* $Id: caret.c,v 1.13 2004/07/30 09:16:06 weiden Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -262,7 +262,7 @@
     return FALSE;
   }
   
-  IntRemoveTimer(hWnd, IDCARETTIMER, PsGetCurrentThreadId(), TRUE);
+  IntRemoveTimer(hWnd, IDCARETTIMER, TRUE);
   
   ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
   
@@ -347,7 +347,7 @@
   
   if(ThreadQueue->CaretInfo->Visible)
   {
-    IntRemoveTimer(hWnd, IDCARETTIMER, PsGetCurrentThreadId(), TRUE);
+    IntRemoveTimer(hWnd, IDCARETTIMER, TRUE);
     
     IntHideCaret(ThreadQueue->CaretInfo);
     ThreadQueue->CaretInfo->Visible = 0;

reactos/subsys/win32k/ntuser
msgqueue.c 1.100 -> 1.101
diff -u -r1.100 -r1.101
--- msgqueue.c	22 May 2004 17:51:08 -0000	1.100
+++ msgqueue.c	30 Jul 2004 09:16:06 -0000	1.101
@@ -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.100 2004/05/22 17:51:08 weiden Exp $
+/* $Id: msgqueue.c,v 1.101 2004/07/30 09:16:06 weiden Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -729,7 +729,7 @@
   PUSER_SENT_MESSAGE Message;
   PLIST_ENTRY Entry;
   LRESULT Result;
-  BOOL Freed;
+  BOOL Freed, Wake;
   PUSER_SENT_MESSAGE_NOTIFY NotifyMessage;
 
   IntLockMessageQueue(MessageQueue);
@@ -775,22 +775,18 @@
      MsqSendMessage() function (if timed out) */
   
   /* Let the sender know the result. */
-  if (Message->Result != NULL)
-    {
-      *Message->Result = Result;
-    }
+  Message->Result = Result;
+
+  Wake = (Message->Flags & USMF_WAKE_SENDER) != 0;
 
   /* Notify the sender. */
-  if (Message->CompletionEvent != NULL)
+  if (Wake)
     {
-      KeSetEvent(Message->CompletionEvent, IO_NO_INCREMENT, FALSE);
+      KeSetEvent(&Message->CompletionEvent, IO_NO_INCREMENT, FALSE);
     }
-  
-  /* unlock the sender's message queue, the safe operation is done */
-  IntUnLockMessageQueue(Message->SenderQueue);
 
   /* Notify the sender if they specified a callback. */
-  if (!Freed && Message->CompletionCallback != NULL)
+  if (!Freed && Wake)
     {
       if(!(NotifyMessage = ExAllocatePoolWithTag(NonPagedPool,
 					         sizeof(USER_SENT_MESSAGE_NOTIFY), TAG_USRMSG)))
@@ -798,6 +794,7 @@
         DPRINT1("MsqDispatchOneSentMessage(): Not enough memory to create a callback notify message\n");
         goto Notified;
       }
+      /* FIXME
       NotifyMessage->CompletionCallback =
 	Message->CompletionCallback;
       NotifyMessage->CompletionCallbackContext =
@@ -806,16 +803,23 @@
       NotifyMessage->hWnd = Message->Msg.hwnd;
       NotifyMessage->Msg = Message->Msg.message;
       MsqSendNotifyMessage(Message->SenderQueue, NotifyMessage);
+      */
     }
 
 Notified:
+  /* unlock the sender's message queue, the safe operation is done */
+  IntUnLockMessageQueue(Message->SenderQueue);
+  if(!Wake)
+  {
+    IntDereferenceMessageQueue(Message->SenderQueue);
+  }
+  
   if(!Freed)
   {
     /* only dereference our message queue if the message has not been timed out */
     IntDereferenceMessageQueue(MessageQueue);
   }
   
-  /* only free the message if not freed already */
   ExFreePool(Message);
   return(TRUE);
 }
@@ -837,9 +841,7 @@
                UINT uTimeout, BOOL Block, ULONG_PTR *uResult)
 {
   PUSER_SENT_MESSAGE Message;
-  KEVENT CompletionEvent;
   NTSTATUS WaitStatus;
-  LRESULT Result;
   PUSER_MESSAGE_QUEUE ThreadQueue;
   LARGE_INTEGER Timeout;
   PLIST_ENTRY Entry;
@@ -850,26 +852,24 @@
     return STATUS_INSUFFICIENT_RESOURCES;
   }
   
-  KeInitializeEvent(&CompletionEvent, NotificationEvent, FALSE);
+  KeInitializeEvent(&Message->CompletionEvent, NotificationEvent, FALSE);
   
   ThreadQueue = PsGetWin32Thread()->MessageQueue;
   ASSERT(ThreadQueue != MessageQueue);
   
   Timeout.QuadPart = uTimeout * -10000;
   
-  /* FIXME - increase reference counter of sender's message queue here */
-  
-  Result = 0;
   Message->Msg.hwnd = Wnd;
   Message->Msg.message = Msg;
   Message->Msg.wParam = wParam;
   Message->Msg.lParam = lParam;
-  Message->CompletionEvent = &CompletionEvent;
-  Message->Result = &Result;
+  Message->Result = 0;
+  Message->Flags = USMF_WAKE_SENDER;
   Message->SenderQueue = ThreadQueue;
   Message->CompletionCallback = NULL;
   
   IntReferenceMessageQueue(MessageQueue);
+  IntReferenceMessageQueue(ThreadQueue);
   
   /* add it to the list of pending messages */
   IntLockMessageQueue(ThreadQueue);
@@ -888,11 +888,11 @@
   if(Block)
   {
     /* don't process messages sent to the thread */
-    WaitStatus = KeWaitForSingleObject(&CompletionEvent, UserRequest, UserMode, 
+    WaitStatus = KeWaitForSingleObject(&Message->CompletionEvent, UserRequest, UserMode,
                                        FALSE, (uTimeout ? &Timeout : NULL));
     if(WaitStatus == STATUS_TIMEOUT)
       {
-        /* look up if the message has not yet dispatched, if so
+        /* look up if the message has not yet been dispatched, if so
            make sure it can't pass a result and it must not set the completion event anymore */
 	IntLockMessageQueue(MessageQueue);
         Entry = MessageQueue->SentMessagesListHead.Flink;
@@ -901,10 +901,11 @@
             if ((PUSER_SENT_MESSAGE) CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry)
                 == Message)
               {
-                /* we can access Message here, it's secure because the message queue is locked
+                IntLockMessageQueue(ThreadQueue);
+                /* we can access Message here, it's secure because the sender message queue is locked
                    and the message is still hasn't been dispatched */
-		Message->CompletionEvent = NULL;
-                Message->Result = NULL;
+		Message->Flags &= ~USMF_WAKE_SENDER;
+		IntUnLockMessageQueue(ThreadQueue);
                 break;
               }
             Entry = Entry->Flink;
@@ -924,8 +925,7 @@
                    and the message has definitely not yet been destroyed, otherwise it would
                    have been removed from this list by the dispatching routine right after
 		   dispatching the message */
-		Message->CompletionEvent = NULL;
-                Message->Result = NULL;
+                Message->Flags &= ~USMF_WAKE_SENDER;
                 RemoveEntryList(&Message->DispatchingListEntry);
                 IntDereferenceMessageQueue(MessageQueue);
                 break;
@@ -942,7 +942,7 @@
   {
     PVOID WaitObjects[2];
     
-    WaitObjects[0] = &CompletionEvent;
+    WaitObjects[0] = &Message->CompletionEvent;
     WaitObjects[1] = &ThreadQueue->NewMessages;
     do
       {
@@ -959,10 +959,11 @@
                 if ((PUSER_SENT_MESSAGE) CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry)
                     == Message)
                   {
-                    /* we can access Message here, it's secure because the message queue is locked
+                    IntLockMessageQueue(ThreadQueue);
+                    /* we can access Message here, it's secure because the sender message queue is locked
                        and the message is still hasn't been dispatched */
-		    Message->CompletionEvent = NULL;
-                    Message->Result = NULL;
+                    Message->Flags &= ~USMF_WAKE_SENDER;
+                    IntUnLockMessageQueue(ThreadQueue);
                     break;
                   }
                 Entry = Entry->Flink;
@@ -982,8 +983,7 @@
                        and the message has definitely not yet been destroyed, otherwise it would
                        have been removed from this list by the dispatching routine right after
 		       dispatching the message */
-		    Message->CompletionEvent = NULL;
-                    Message->Result = NULL;
+                    Message->Flags &= ~USMF_WAKE_SENDER;
                     RemoveEntryList(&Message->DispatchingListEntry);
                     IntDereferenceMessageQueue(MessageQueue);
                     break;
@@ -1001,7 +1001,13 @@
   }
   
   if(WaitStatus != STATUS_TIMEOUT)
-    *uResult = (STATUS_WAIT_0 == WaitStatus ? Result : -1);
+  {
+    *uResult = (STATUS_WAIT_0 == WaitStatus ? Message->Result : -1);
+  }
+  else
+  {
+    IntDereferenceMessageQueue(ThreadQueue);
+  }
   
   return WaitStatus;
 }
@@ -1159,9 +1165,9 @@
       }
       
       /* wake the sender's thread */
-      if (CurrentSentMessage->CompletionEvent != NULL)
+      if (CurrentSentMessage->Flags & USMF_WAKE_SENDER)
       {
-        KeSetEvent(CurrentSentMessage->CompletionEvent, IO_NO_INCREMENT, FALSE);
+        KeSetEvent(&CurrentSentMessage->CompletionEvent, IO_NO_INCREMENT, FALSE);
       }
       
       /* dereference our message queue */
@@ -1182,9 +1188,9 @@
       DPRINT("Notify the sender, the thread has been terminated while dispatching a message!\n");
       
       /* wake the sender's thread */
-      if (CurrentSentMessage->CompletionEvent != NULL)
+      if (CurrentSentMessage->Flags & USMF_WAKE_SENDER)
       {
-        KeSetEvent(CurrentSentMessage->CompletionEvent, IO_NO_INCREMENT, FALSE);
+        KeSetEvent(&CurrentSentMessage->CompletionEvent, IO_NO_INCREMENT, FALSE);
       }
       
       /* dereference our message queue */

reactos/subsys/win32k/ntuser
timer.c 1.33 -> 1.34
diff -u -r1.33 -r1.34
--- timer.c	29 Jun 2004 23:45:31 -0000	1.33
+++ timer.c	30 Jul 2004 09:16:06 -0000	1.34
@@ -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: timer.c,v 1.33 2004/06/29 23:45:31 navaraf Exp $
+/* $Id: timer.c,v 1.34 2004/07/30 09:16:06 weiden Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -85,10 +85,11 @@
 
 //must hold mutex while calling this
 PMSG_TIMER_ENTRY FASTCALL
-IntRemoveTimer(HWND hWnd, UINT_PTR IDEvent, HANDLE ThreadID, BOOL SysTimer)
+IntRemoveTimer(HWND hWnd, UINT_PTR IDEvent, BOOL SysTimer)
 {
   PMSG_TIMER_ENTRY MsgTimer;
   PLIST_ENTRY EnumEntry;
+  PUSER_MESSAGE_QUEUE MessageQueue = PsGetWin32Thread()->MessageQueue;
   
   //remove timer if already in the queue
   EnumEntry = TimerListHead.Flink;
@@ -99,7 +100,7 @@
       
     if (MsgTimer->Msg.hwnd == hWnd && 
         MsgTimer->Msg.wParam == (WPARAM)IDEvent &&
-        MsgTimer->ThreadID == ThreadID &&
+        MsgTimer->MessageQueue == MessageQueue &&
         (MsgTimer->Msg.message == WM_SYSTIMER) == SysTimer)
     {
       RemoveEntryList(&MsgTimer->ListEntry);
@@ -115,11 +116,16 @@
  * NOTE: It doesn't kill the timer. It just removes them from the list.
  */
 VOID FASTCALL
-RemoveTimersThread(HANDLE ThreadID)
+RemoveTimersThread(PUSER_MESSAGE_QUEUE MessageQueue)
 {
   PMSG_TIMER_ENTRY MsgTimer;
   PLIST_ENTRY EnumEntry;
   
+  if(MessageQueue == NULL)
+  {
+    return;
+  }
+  
   IntLockTimerList();
   
   EnumEntry = TimerListHead.Flink;
@@ -128,7 +134,7 @@
     MsgTimer = CONTAINING_RECORD(EnumEntry, MSG_TIMER_ENTRY, ListEntry);
     EnumEntry = EnumEntry->Flink;
     
-    if (MsgTimer->ThreadID == ThreadID)
+    if (MsgTimer->MessageQueue == MessageQueue)
     {
       if (MsgTimer->Msg.hwnd == NULL)
       {
@@ -136,6 +142,9 @@
       }
       
       RemoveEntryList(&MsgTimer->ListEntry);
+      
+      IntDereferenceMessageQueue(MsgTimer->MessageQueue);
+      
       ExFreePool(MsgTimer);
     }
   }
@@ -164,6 +173,9 @@
     if (MsgTimer->Msg.hwnd == Wnd)
     {
       RemoveEntryList(&MsgTimer->ListEntry);
+      
+      IntDereferenceMessageQueue(MsgTimer->MessageQueue);
+      
       ExFreePool(MsgTimer);
     }
   }
@@ -179,10 +191,8 @@
   PMSG_TIMER_ENTRY NewTimer;
   LARGE_INTEGER CurrentTime;
   PWINDOW_OBJECT WindowObject;
-  HANDLE ThreadID;
   UINT_PTR Ret = 0;
  
-  ThreadID = PsGetCurrentThreadId();
   KeQuerySystemTime(&CurrentTime);
   IntLockTimerList();
   
@@ -219,7 +229,7 @@
     IntReleaseWindowObject(WindowObject);
     
     /* remove timer if already in the queue */
-    MsgTimer = IntRemoveTimer(hWnd, nIDEvent, ThreadID, SystemTimer); 
+    MsgTimer = IntRemoveTimer(hWnd, nIDEvent, SystemTimer);
   }
   
   #if 1
@@ -266,7 +276,9 @@
     NewTimer->Msg.lParam = (LPARAM)lpTimerFunc;
     NewTimer->Period = uElapse;
     NewTimer->Timeout.QuadPart = CurrentTime.QuadPart + (uElapse * 10000);
-    NewTimer->ThreadID = ThreadID;
+    NewTimer->MessageQueue = PsGetWin32Thread()->MessageQueue;
+    
+    IntReferenceMessageQueue(NewTimer->MessageQueue);
   }
   
   Ret = nIDEvent; // FIXME - return lpTimerProc if it's not a system timer
@@ -322,7 +334,7 @@
     IntReleaseWindowObject(WindowObject);
   }
   
-  MsgTimer = IntRemoveTimer(hWnd, uIDEvent, PsGetCurrentThreadId(), SystemTimer);
+  MsgTimer = IntRemoveTimer(hWnd, uIDEvent, SystemTimer);
   
   IntUnLockTimerList();
   
@@ -333,6 +345,8 @@
     return FALSE;
   }
   
+  IntReferenceMessageQueue(MsgTimer->MessageQueue);
+  
   /* FIXME: use lookaside? */
   ExFreePool(MsgTimer);
   
@@ -346,9 +360,6 @@
   LARGE_INTEGER CurrentTime;
   PLIST_ENTRY EnumEntry;
   PMSG_TIMER_ENTRY MsgTimer;
-  PETHREAD Thread;
-  PETHREAD *ThreadsToDereference;
-  ULONG ThreadsToDereferenceCount, ThreadsToDereferencePos, i;
   
   for(;;)
   {
@@ -363,8 +374,6 @@
       KEBUGCHECK(0);
     }
     
-    ThreadsToDereferenceCount = ThreadsToDereferencePos = 0;
-    
     IntLockTimerList();
     
     KeQuerySystemTime(&CurrentTime);
@@ -374,16 +383,10 @@
          EnumEntry = EnumEntry->Flink)
     {
        MsgTimer = CONTAINING_RECORD(EnumEntry, MSG_TIMER_ENTRY, ListEntry);
-       if (CurrentTime.QuadPart >= MsgTimer->Timeout.QuadPart)
-          ++ThreadsToDereferenceCount;
-       else
+       if (CurrentTime.QuadPart < MsgTimer->Timeout.QuadPart)
           break;
     }
 
-
-    ThreadsToDereference = (PETHREAD *)ExAllocatePoolWithTag(
-       NonPagedPool, ThreadsToDereferenceCount * sizeof(PETHREAD), TAG_TIMERTD);
-
     EnumEntry = TimerListHead.Flink;
     while (EnumEntry != &TimerListHead)
     {
@@ -399,16 +402,7 @@
          * FIXME: 1) Find a faster way of getting the thread message queue? (lookup by id is slow)
          */
         
-        if (!NT_SUCCESS(PsLookupThreadByThreadId(MsgTimer->ThreadID, &Thread)))
-        {
-          ExFreePool(MsgTimer);
-          continue;
-        }
-        
-        MsqPostMessage(((PW32THREAD)Thread->Win32Thread)->MessageQueue, &MsgTimer->Msg, FALSE);
-        
-        ThreadsToDereference[ThreadsToDereferencePos] = Thread;
-        ++ThreadsToDereferencePos;
+        MsqPostMessage(MsgTimer->MessageQueue, &MsgTimer->Msg, FALSE);
         
         //set up next periodic timeout
         //FIXME: is this calculation really necesary (and correct)? -Gunnar
@@ -435,11 +429,6 @@
     }
     
     IntUnLockTimerList();
-
-    for (i = 0; i < ThreadsToDereferencePos; i++)
-       ObDereferenceObject(ThreadsToDereference[i]);
-
-     ExFreePool(ThreadsToDereference);
   }
 }
 

reactos/subsys/win32k/objects
text.c 1.107 -> 1.108
diff -u -r1.107 -r1.108
--- text.c	29 Jul 2004 12:03:47 -0000	1.107
+++ text.c	30 Jul 2004 09:16:06 -0000	1.108
@@ -22,7 +22,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: text.c,v 1.107 2004/07/29 12:03:47 weiden Exp $ */
+/* $Id: text.c,v 1.108 2004/07/30 09:16:06 weiden Exp $ */
 #include <w32k.h>
 
 #include <ft2build.h>
@@ -2967,7 +2967,8 @@
 
   RtlFreeUnicodeString(&FaceName);
   TEXTOBJ_UnlockText(FontHandle);
-  ASSERT(! NT_SUCCESS(Status) && NULL != TextObj->GDIFontHandle);
+  
+  ASSERT((NT_SUCCESS(Status) ^ (NULL == TextObj->GDIFontHandle)) != 0);
 
   return Status;
 }
CVSspam 0.2.8