Bug 542821 - 'Process startup event gets dropped on the floor by deferred messaging'. r=jimm.
authorBen Turner <bent.mozilla@gmail.com>
Wed, 03 Feb 2010 13:09:55 -0800
changeset 37882 9ffbf751fdcc3e3a7712f0b359e46618385260dd
parent 37881 91ba24bd17ed6198ba9c8655ab6d3dbbb9123c3b
child 37883 4f2520c904e5827eb8115649a81c1579bdd11c05
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm
bugs542821
milestone1.9.3a1pre
Bug 542821 - 'Process startup event gets dropped on the floor by deferred messaging'. r=jimm.
ipc/glue/WindowsMessageLoop.cpp
ipc/glue/WindowsMessageLoop.h
--- a/ipc/glue/WindowsMessageLoop.cpp
+++ b/ipc/glue/WindowsMessageLoop.cpp
@@ -240,16 +240,22 @@ ProcessOrDeferMessage(HWND hwnd,
       deferred = new DeferredWindowPosMessage(hwnd, lParam);
       break;
     }
     case WM_NCCALCSIZE: {
       deferred = new DeferredWindowPosMessage(hwnd, lParam, true, wParam);
       break;
     }
 
+    case WM_COPYDATA: {
+      deferred = new DeferredCopyDataMessage(hwnd, uMsg, wParam, lParam);
+      res = TRUE;
+      break;
+    }
+
     // Messages that are safe to pass to DefWindowProc go here.
     case WM_GETICON:
     case WM_GETMINMAXINFO:
     case WM_GETTEXT:
     case WM_NCHITTEST:
     case WM_SETICON:
     case WM_SYNCPAINT: // Intentional fall-through.
     case WM_WINDOWPOSCHANGING: {
@@ -720,8 +726,44 @@ DeferredWindowPosMessage::Run()
 
 #ifdef DEBUG
   BOOL ret = 
 #endif
   SetWindowPos(windowPos.hwnd, windowPos.hwndInsertAfter, windowPos.x,
                windowPos.y, windowPos.cx, windowPos.cy, windowPos.flags);
   NS_ASSERTION(ret, "SetWindowPos failed!");
 }
+
+DeferredCopyDataMessage::DeferredCopyDataMessage(HWND aHWnd,
+                                                 UINT aMessage,
+                                                 WPARAM aWParam,
+                                                 LPARAM aLParam)
+: DeferredSendMessage(aHWnd, aMessage, aWParam, aLParam)
+{
+  NS_ASSERTION(IsWindow(reinterpret_cast<HWND>(aWParam)), "Bad window!");
+
+  COPYDATASTRUCT* source = reinterpret_cast<COPYDATASTRUCT*>(aLParam);
+  NS_ASSERTION(source, "Should never be null!");
+
+  copyData.dwData = source->dwData;
+  copyData.cbData = source->cbData;
+
+  if (source->cbData) {
+    copyData.lpData = malloc(source->cbData);
+    if (copyData.lpData) {
+      memcpy(copyData.lpData, source->lpData, source->cbData);
+    }
+    else {
+      NS_ERROR("Out of memory?!");
+      copyData.cbData = 0;
+    }
+  }
+  else {
+    copyData.lpData = NULL;
+  }
+
+  lParam = reinterpret_cast<LPARAM>(&copyData);
+}
+
+DeferredCopyDataMessage::~DeferredCopyDataMessage()
+{
+  free(copyData.lpData);
+}
--- a/ipc/glue/WindowsMessageLoop.h
+++ b/ipc/glue/WindowsMessageLoop.h
@@ -149,13 +149,27 @@ public:
                            WPARAM aWParam = 0);
 
   virtual void Run();
 
 private:
   WINDOWPOS windowPos;
 };
 
+// This class duplicates a data buffer for a WM_COPYDATA message.
+class DeferredCopyDataMessage : public DeferredSendMessage
+{
+public:
+  DeferredCopyDataMessage(HWND aHWnd,
+                          UINT aMessage,
+                          WPARAM aWParam,
+                          LPARAM aLParam);
+
+  ~DeferredCopyDataMessage();
+private:
+  COPYDATASTRUCT copyData;
+};
+
 } /* namespace windows */
 } /* namespace ipc */
 } /* namespace mozilla */
 
 #endif /* IPC_GLUE_WINDOWSMESSAGELOOP_H */