Bug 542337 - '[OOPP] hang in test_plugin_clipping2.xhtml' r=jimm.

This commit is contained in:
Ben Turner 2010-01-28 11:32:41 -08:00
parent 731c252671
commit 2e9585e002
5 changed files with 32 additions and 41 deletions

View File

@ -15,10 +15,10 @@
</hbox>
<div id="d1" style="width:200px; overflow:hidden; position:absolute; top:0; left:0;">
<embed id="p1" type="application/x-test" wmode="window" style="position:relative" drawmode="solid"></embed>
<embed id="p1" type="application/x-test" wmode="window" style="position:relative"></embed>
</div>
<div id="d2" style="width:200px; height:200px; overflow:hidden; position:absolute; top:100px; left:0;">
<embed id="p2" type="application/x-test" wmode="window" drawmode="solid"></embed>
<embed id="p2" type="application/x-test" wmode="window"></embed>
<div id="zbox" style="position:absolute; left:50px; top:50px; width:100px; height:100px; background:yellow;">
</div>
</div>

View File

@ -545,7 +545,14 @@ nsresult nsPluginNativeWindowWin::SubclassAndAssociateWindow()
return NS_OK;
LONG style = GetWindowLongPtr(hWnd, GWL_STYLE);
#ifdef MOZ_IPC
// Out of process plugins must not have the WS_CLIPCHILDREN style set on their
// parent windows or else synchronous paints (via UpdateWindow() and others)
// will cause deadlocks.
style &= ~WS_CLIPCHILDREN;
#else
style |= WS_CLIPCHILDREN;
#endif
SetWindowLongPtr(hWnd, GWL_STYLE, style);
mPluginWinProc = SubclassWindow(hWnd, (LONG_PTR)PluginWndProc);

View File

@ -106,8 +106,6 @@
#ifdef MOZ_IPC
#include "mozilla/ipc/SyncChannel.h"
#include "mozilla/plugins/PluginInstanceParent.h"
using mozilla::plugins::PluginInstanceParent;
#endif
#include "nsWindow.h"
@ -2108,7 +2106,7 @@ NS_METHOD nsWindow::Invalidate(PRBool aIsSynchronous)
VERIFY(::InvalidateRect(mWnd, NULL, FALSE));
if (aIsSynchronous) {
UpdateWindowInternal(mWnd);
VERIFY(::UpdateWindow(mWnd));
}
}
return NS_OK;
@ -2142,7 +2140,7 @@ NS_METHOD nsWindow::Invalidate(const nsIntRect & aRect, PRBool aIsSynchronous)
VERIFY(::InvalidateRect(mWnd, &rect, FALSE));
if (aIsSynchronous) {
UpdateWindowInternal(mWnd);
VERIFY(::UpdateWindow(mWnd));
}
}
return NS_OK;
@ -2186,7 +2184,7 @@ NS_IMETHODIMP nsWindow::Update()
// updates can come through for windows no longer holding an mWnd during
// deletes triggered by JavaScript in buttons with mouse feedback
if (mWnd)
UpdateWindowInternal(mWnd);
VERIFY(::UpdateWindow(mWnd));
return rv;
}
@ -3146,14 +3144,8 @@ BOOL CALLBACK nsWindow::DispatchStarvedPaints(HWND aWnd, LPARAM aMsg)
// its one of our windows so check to see if it has a
// invalidated rect. If it does. Dispatch a synchronous
// paint.
if (GetUpdateRect(aWnd, NULL, FALSE)) {
nsWindow* win = GetNSWindowPtr(aWnd);
if (win)
win->UpdateWindowInternal(aWnd);
else
// Bad, this could hang a plugin process. Is this possible?
VERIFY(::UpdateWindow(aWnd));
}
if (GetUpdateRect(aWnd, NULL, FALSE))
VERIFY(::UpdateWindow(aWnd));
}
return TRUE;
}
@ -7118,30 +7110,6 @@ LPARAM nsWindow::lParamToClient(LPARAM lParam)
return MAKELPARAM(pt.x, pt.y);
}
// If this window hosts a plugin window from another process then we cannot use
// the windows UpdateWindow function to update it. Doing so sends a synchronous
// WM_PAINT message to the plugin process which may call back to this process
// in response. As this process is waiting for the UpdateWindow call to return
// we deadlock. To work around this we issue an IPC call to the plugin process
// to force the redraw since the IPC call handles reentrancy properly.
void nsWindow::UpdateWindowInternal(HWND aWnd)
{
if (aWnd) {
#ifdef MOZ_IPC
if (mWindowType == eWindowType_plugin) {
PluginInstanceParent* instance = reinterpret_cast<PluginInstanceParent*>(
::GetPropW(aWnd, L"PluginInstanceParentProperty"));
if (instance) {
if (!instance->CallUpdateWindow())
NS_ERROR("Failed to send message!");
return;
}
}
#endif
VERIFY(::UpdateWindow(aWnd));
}
}
/**************************************************************
**************************************************************
**

View File

@ -403,8 +403,6 @@ protected:
static STDMETHODIMP_(LRESULT) LresultFromObject(REFIID riid, WPARAM wParam, LPUNKNOWN pAcc);
#endif // ACCESSIBILITY
void UpdateWindowInternal(HWND aWnd);
protected:
nsIntSize mLastSize;
nsIntPoint mLastPoint;

View File

@ -53,6 +53,11 @@
**************************************************************
**************************************************************/
#ifdef MOZ_IPC
#include "mozilla/plugins/PluginInstanceParent.h"
using mozilla::plugins::PluginInstanceParent;
#endif
#include "nsWindowGfx.h"
#include <windows.h>
#include "nsIRegion.h"
@ -322,6 +327,19 @@ EnsureSharedSurfaceSize(gfxIntSize size)
PRBool nsWindow::OnPaint(HDC aDC)
{
#ifdef MOZ_IPC
if (mWindowType == eWindowType_plugin) {
PluginInstanceParent* instance = reinterpret_cast<PluginInstanceParent*>(
::GetPropW(mWnd, L"PluginInstanceParentProperty"));
if (instance) {
if (!instance->CallUpdateWindow())
NS_ERROR("Failed to send message!");
ValidateRect(mWnd, NULL);
return PR_TRUE;
}
}
#endif
nsPaintEvent willPaintEvent(PR_TRUE, NS_WILL_PAINT, this);
DispatchWindowEvent(&willPaintEvent);