Bug 627084 - Add an app shell native event starvation timeout for cases where our native event pump messages get dropped by 3rd party code. r=roc
authorJim Mathies <jmathies@mozilla.com>
Tue, 09 Aug 2011 09:48:10 -0500
changeset 74119 3015d5cb3a9c493d3d53f828a2a42e1ea7d86419
parent 74118 13d1b63d5a696dafaa9c92391316c4edf7f2858c
child 74120 e9f6607a3990d027d09dcdc3395fe76be4ef9e6b
push id20955
push usereakhgari@mozilla.com
push dateWed, 10 Aug 2011 14:22:13 +0000
treeherdermozilla-central@93328efd3d77 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs627084
milestone8.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 627084 - Add an app shell native event starvation timeout for cases where our native event pump messages get dropped by 3rd party code. r=roc
widget/src/windows/nsAppShell.cpp
widget/src/windows/nsAppShell.h
--- a/widget/src/windows/nsAppShell.cpp
+++ b/widget/src/windows/nsAppShell.cpp
@@ -49,16 +49,19 @@
 
 // For skidmark code
 #include <windows.h> 
 #include <tlhelp32.h> 
 
 const PRUnichar* kAppShellEventId = L"nsAppShell:EventID";
 const PRUnichar* kTaskbarButtonEventId = L"TaskbarButtonCreated";
 
+// The maximum time we allow before forcing a native event callback
+#define NATIVE_EVENT_STARVATION_LIMIT mozilla::TimeDuration::FromSeconds(1)
+
 static UINT sMsgId;
 
 #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
 static UINT sTaskbarButtonCreatedMsg;
 
 /* static */
 UINT nsAppShell::GetTaskbarButtonCreatedMessage() {
 	return sTaskbarButtonCreatedMsg;
@@ -130,16 +133,18 @@ nsAppShell::~nsAppShell()
 
 nsresult
 nsAppShell::Init()
 {
 #ifdef MOZ_CRASHREPORTER
   LSPAnnotate();
 #endif
 
+  mLastNativeEventScheduled = TimeStamp::Now();
+
   if (!sMsgId)
     sMsgId = RegisterWindowMessageW(kAppShellEventId);
 
 #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
   sTaskbarButtonCreatedMsg = ::RegisterWindowMessageW(kTaskbarButtonEventId);
   NS_ASSERTION(sTaskbarButtonCreatedMsg, "Could not register taskbar button creation message");
 
   // Global app registration id for Win7 and up. See
@@ -301,16 +306,19 @@ nsAppShell::DoProcessMoreGeckoEvents()
   }
 }
 
 void
 nsAppShell::ScheduleNativeEventCallback()
 {
   // Post a message to the hidden message window
   NS_ADDREF_THIS(); // will be released when the event is processed
+  // Time stamp this event so we can detect cases where the event gets
+  // dropping in sub classes / modal loops we do not control. 
+  mLastNativeEventScheduled = TimeStamp::Now();
   ::PostMessage(mEventWnd, sMsgId, 0, reinterpret_cast<LPARAM>(this));
 }
 
 PRBool
 nsAppShell::ProcessNextNativeEvent(PRBool mayWait)
 {
 #if defined(_MSC_VER) && defined(_M_IX86)
   if (sXPCOMHasLoadedNewDLLs && sLoadedModules) {
@@ -343,10 +351,17 @@ nsAppShell::ProcessNextNativeEvent(PRBoo
     }
   } while (!gotMessage && mayWait);
 
   // See DoProcessNextNativeEvent, mEventloopNestingLevel will be
   // one when a modal loop unwinds.
   if (mNativeCallbackPending && mEventloopNestingLevel == 1)
     DoProcessMoreGeckoEvents();
 
+  // Check for starved native callbacks. If we haven't processed one
+  // of these events in NATIVE_EVENT_STARVATION_LIMIT, fire one off.
+  if ((TimeStamp::Now() - mLastNativeEventScheduled) >
+      NATIVE_EVENT_STARVATION_LIMIT) {
+    ScheduleNativeEventCallback();
+  }
+  
   return gotMessage;
 }
--- a/widget/src/windows/nsAppShell.h
+++ b/widget/src/windows/nsAppShell.h
@@ -35,27 +35,29 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsAppShell_h__
 #define nsAppShell_h__
 
 #include "nsBaseAppShell.h"
 #include <windows.h>
+#include "mozilla/TimeStamp.h"
 
 /**
  * Native Win32 Application shell wrapper
  */
 class nsAppShell : public nsBaseAppShell
 {
 public:
   nsAppShell() :
     mEventWnd(NULL),
     mNativeCallbackPending(PR_FALSE)
   {}
+  typedef mozilla::TimeStamp TimeStamp;
 
   nsresult Init();
   void DoProcessMoreGeckoEvents();
 
 #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
   static UINT GetTaskbarButtonCreatedMessage();
 #endif
 
@@ -67,11 +69,12 @@ protected:
   virtual PRBool ProcessNextNativeEvent(PRBool mayWait);
   virtual ~nsAppShell();
 
   static LRESULT CALLBACK EventWindowProc(HWND, UINT, WPARAM, LPARAM);
 
 protected:
   HWND mEventWnd;
   PRBool mNativeCallbackPending;
+  TimeStamp mLastNativeEventScheduled;
 };
 
 #endif // nsAppShell_h__