Bug 1234838 - Update the windows backwards time skew fix code to use a PostMessage rather than a gecko NS_DispatchToMainThread. r=karlt
authorKartikaya Gupta <kgupta@mozilla.com>
Tue, 12 Jan 2016 11:53:55 -0500
changeset 314728 d081f975bf1707be39ffeb08a59905cb6f3e2ee6
parent 314727 2feec42daf62c891583af3e77834344db33afac2
child 314729 b7a4595a79011dc47a6ac00eee59969586cccbe9
push id5703
push userraliiev@mozilla.com
push dateMon, 07 Mar 2016 14:18:41 +0000
treeherdermozilla-beta@31e373ad5b5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskarlt
bugs1234838
milestone46.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 1234838 - Update the windows backwards time skew fix code to use a PostMessage rather than a gecko NS_DispatchToMainThread. r=karlt
widget/windows/nsWindow.cpp
widget/windows/nsWindow.h
widget/windows/nsWindowDefs.h
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -255,29 +255,62 @@ TimeConverter() {
   static SystemTimeConverter<DWORD> timeConverterSingleton;
   return timeConverterSingleton;
 }
 
 namespace mozilla {
 
 class CurrentWindowsTimeGetter {
 public:
+  CurrentWindowsTimeGetter(HWND aWnd)
+    : mWnd(aWnd)
+  {
+  }
+
   DWORD GetCurrentTime() const
   {
     return ::GetTickCount();
   }
 
   void GetTimeAsyncForPossibleBackwardsSkew(const TimeStamp& aNow)
   {
-    NS_DispatchToMainThread(NS_NewRunnableFunction([aNow]() {
-      TimeConverter().CompensateForBackwardsSkew(::GetMessageTime(), aNow);
-    }));
-  }
+    DWORD currentTime = GetCurrentTime();
+    if (sBackwardsSkewStamp && currentTime == sLastPostTime) {
+      // There's already one inflight with this timestamp. Don't
+      // send a duplicate.
+      return;
+    }
+    sBackwardsSkewStamp = Some(aNow);
+    sLastPostTime = currentTime;
+    static_assert(sizeof(WPARAM) >= sizeof(DWORD), "Can't fit a DWORD in a WPARAM");
+    ::PostMessage(mWnd, MOZ_WM_SKEWFIX, sLastPostTime, 0);
+  }
+
+  static bool GetAndClearBackwardsSkewStamp(DWORD aPostTime, TimeStamp* aOutSkewStamp)
+  {
+    if (aPostTime != sLastPostTime) {
+      // The SKEWFIX message is stale; we've sent a new one since then.
+      // Ignore this one.
+      return false;
+    }
+    MOZ_ASSERT(sBackwardsSkewStamp);
+    *aOutSkewStamp = sBackwardsSkewStamp.value();
+    sBackwardsSkewStamp = Nothing();
+    return true;
+  }
+
+private:
+  static Maybe<TimeStamp> sBackwardsSkewStamp;
+  static DWORD sLastPostTime;
+  HWND mWnd;
 };
 
+Maybe<TimeStamp> CurrentWindowsTimeGetter::sBackwardsSkewStamp;
+DWORD CurrentWindowsTimeGetter::sLastPostTime = 0;
+
 } // namespace mozilla
 
 /**************************************************************
  *
  * SECTION: globals variables
  *
  **************************************************************/
 
@@ -5699,16 +5732,25 @@ nsWindow::ProcessMessage(UINT msg, WPARA
     {
       WidgetContentCommandEvent command(true, eContentCommandRedo, this, true);
       DispatchWindowEvent(&command);
       *aRetValue = (LRESULT)(command.mSucceeded && command.mIsEnabled);
       result = true;
     }
     break;
 
+    case MOZ_WM_SKEWFIX:
+    {
+      TimeStamp skewStamp;
+      if (CurrentWindowsTimeGetter::GetAndClearBackwardsSkewStamp(wParam, &skewStamp)) {
+        TimeConverter().CompensateForBackwardsSkew(::GetMessageTime(), skewStamp);
+      }
+    }
+    break;
+
     default:
     {
       if (msg == nsAppShell::GetTaskbarButtonCreatedMessage()) {
         SetHasTaskbarIconBeenCreated();
       }
     }
     break;
 
@@ -5901,17 +5943,17 @@ nsWindow::ClientMarginHitTestPoint(int32
   }
 
   return testResult;
 }
 
 TimeStamp
 nsWindow::GetMessageTimeStamp(LONG aEventTime)
 {
-  CurrentWindowsTimeGetter getCurrentTime;
+  CurrentWindowsTimeGetter getCurrentTime(mWnd);
   return TimeConverter().GetTimeStampFromSystemTime(aEventTime,
                                                     getCurrentTime);
 }
 
 void nsWindow::PostSleepWakeNotification(const bool aIsSleepMode)
 {
   if (aIsSleepMode == gIsSleepMode)
     return;
--- a/widget/windows/nsWindow.h
+++ b/widget/windows/nsWindow.h
@@ -385,17 +385,17 @@ protected:
                                               bool *aEventDispatched);
   LRESULT                 ProcessKeyDownMessage(const MSG &aMsg,
                                                 bool *aEventDispatched);
   static bool             EventIsInsideWindow(nsWindow* aWindow);
   // Convert nsEventStatus value to a windows boolean
   static bool             ConvertStatus(nsEventStatus aStatus);
   static void             PostSleepWakeNotification(const bool aIsSleepMode);
   int32_t                 ClientMarginHitTestPoint(int32_t mx, int32_t my);
-  static TimeStamp        GetMessageTimeStamp(LONG aEventTime);
+  TimeStamp               GetMessageTimeStamp(LONG aEventTime);
   static void             UpdateFirstEventTime(DWORD aEventTime);
 
   /**
    * Event handlers
    */
   virtual void            OnDestroy() override;
   virtual bool            OnResize(nsIntRect &aWindowRect);
   bool                    OnGesture(WPARAM wParam, LPARAM lParam);
--- a/widget/windows/nsWindowDefs.h
+++ b/widget/windows/nsWindowDefs.h
@@ -34,16 +34,19 @@
 #define MOZ_WM_MOUSEWHEEL_FIRST           MOZ_WM_MOUSEVWHEEL
 #define MOZ_WM_MOUSEWHEEL_LAST            MOZ_WM_HSCROLL
 // If a popup window is being activated, we try to reactivate the previous
 // window with this message.
 #define MOZ_WM_REACTIVATE                 (WM_APP+0x0314)
 // If TSFTextStore needs to notify TSF/TIP of layout change later, this
 // message is posted.
 #define MOZ_WM_NOTIY_TSF_OF_LAYOUT_CHANGE (WM_APP+0x0315)
+// Internal message used in correcting backwards clock skew
+#define MOZ_WM_SKEWFIX                    (WM_APP+0x0316)
+
 // Internal message for ensuring the file picker is visible on multi monitor
 // systems, and when the screen resolution changes.
 #define MOZ_WM_ENSUREVISIBLE              (WM_APP+0x374F)
 
 #ifndef SM_CXPADDEDBORDER
 #define SM_CXPADDEDBORDER                 92
 #endif