Skip to content
This repository has been archived by the owner on Oct 3, 2020. It is now read-only.

Commit

Permalink
backing out bug 347743 due to major crasher in 386332
Browse files Browse the repository at this point in the history
  • Loading branch information
mconnor@steelgryphon.com committed Jun 29, 2007
1 parent d6b7412 commit 2a009ab
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 225 deletions.
224 changes: 56 additions & 168 deletions layout/generic/nsObjectFrame.cpp
Expand Up @@ -122,8 +122,6 @@
#include "nsPIPluginHost.h"
#include "nsIPluginDocument.h"

#include "nsThreadUtils.h"

#ifdef MOZ_CAIRO_GFX
#include "gfxContext.h"
#endif
Expand Down Expand Up @@ -334,8 +332,6 @@ class nsPluginInstanceOwner : public nsIPluginInstanceOwner,

nsresult Destroy();

void PrepareToStop(PRBool aDelayedStop);

//nsIEventListener interface
nsEventStatus ProcessEvent(const nsGUIEvent & anEvent);

Expand Down Expand Up @@ -367,11 +363,6 @@ class nsPluginInstanceOwner : public nsIPluginInstanceOwner,
void GUItoMacEvent(const nsGUIEvent& anEvent, EventRecord* origEvent, EventRecord& aMacEvent);
#endif

void SetOwner(nsObjectFrame *aOwner)
{
mOwner = aOwner;
}

private:
void FixUpURLS(const nsString &name, nsAString &value);

Expand All @@ -386,10 +377,6 @@ class nsPluginInstanceOwner : public nsIPluginInstanceOwner,
nsCOMPtr<nsIPluginHost> mPluginHost;
PRPackedBool mContentFocused;
PRPackedBool mWidgetVisible; // used on Mac to store our widget's visible state

// If true, destroy the widget on destruction. Used when plugin stop
// is being delayed to a safer point in time.
PRPackedBool mDestroyWidget;
PRUint16 mNumCachedAttrs;
PRUint16 mNumCachedParams;
char **mCachedAttrParamNames;
Expand Down Expand Up @@ -512,7 +499,7 @@ nsObjectFrame::Destroy()

// we need to finish with the plugin before native window is destroyed
// doing this in the destructor is too late.
StopPluginInternal(PR_TRUE);
StopPlugin();

nsObjectFrameSuper::Destroy();
}
Expand Down Expand Up @@ -1301,7 +1288,7 @@ nsresult
nsObjectFrame::PrepareInstanceOwner()
{
// First, have to stop any possibly running plugins.
StopPluginInternal(PR_FALSE);
StopPlugin();

NS_ASSERTION(!mInstanceOwner, "Must not have an instance owner here");

Expand Down Expand Up @@ -1371,49 +1358,47 @@ nsObjectFrame::Instantiate(const char* aMimeType, nsIURI* aURI)
return rv;
}

class nsStopPluginRunnable : public nsRunnable
{
public:
nsStopPluginRunnable(nsPluginInstanceOwner *aInstanceOwner)
: mInstanceOwner(aInstanceOwner)
{
}

NS_IMETHOD Run();

private:
nsRefPtr<nsPluginInstanceOwner> mInstanceOwner;
};

static void
DoStopPlugin(nsPluginInstanceOwner *aInstanceOwner)
void
nsObjectFrame::StopPlugin()
{
nsCOMPtr<nsIPluginInstance> inst;
aInstanceOwner->GetInstance(*getter_AddRefs(inst));
if (inst) {
nsPluginWindow *win;
aInstanceOwner->GetWindow(win);
nsPluginNativeWindow *window = (nsPluginNativeWindow *)win;
nsCOMPtr<nsIPluginInstance> nullinst;

PRBool doCache = PR_TRUE;
PRBool doCallSetWindowAfterDestroy = PR_FALSE;

// first, determine if the plugin wants to be cached
inst->GetValue(nsPluginInstanceVariable_DoCacheBool, (void *)&doCache);
if (!doCache) {
// then determine if the plugin wants Destroy to be called after
// Set Window. This is for bug 50547.
inst->GetValue(nsPluginInstanceVariable_CallSetWindowAfterDestroyBool,
(void *)&doCallSetWindowAfterDestroy);
if (doCallSetWindowAfterDestroy) {
inst->Stop();
inst->Destroy();

if (window)
window->CallSetWindow(nullinst);
else
inst->SetWindow(nsnull);
if (mInstanceOwner != nsnull) {
nsCOMPtr<nsIPluginInstance> inst;
mInstanceOwner->GetInstance(*getter_AddRefs(inst));
if (inst) {
nsPluginWindow *win;
mInstanceOwner->GetWindow(win);
nsPluginNativeWindow *window = (nsPluginNativeWindow *)win;
nsCOMPtr<nsIPluginInstance> nullinst;

PRBool doCache = PR_TRUE;
PRBool doCallSetWindowAfterDestroy = PR_FALSE;

// first, determine if the plugin wants to be cached
inst->GetValue(nsPluginInstanceVariable_DoCacheBool,
(void *) &doCache);
if (!doCache) {
// then determine if the plugin wants Destroy to be called after
// Set Window. This is for bug 50547.
inst->GetValue(nsPluginInstanceVariable_CallSetWindowAfterDestroyBool,
(void *) &doCallSetWindowAfterDestroy);
if (doCallSetWindowAfterDestroy) {
inst->Stop();
inst->Destroy();

if (window)
window->CallSetWindow(nullinst);
else
inst->SetWindow(nsnull);
}
else {
if (window)
window->CallSetWindow(nullinst);
else
inst->SetWindow(nsnull);

inst->Stop();
inst->Destroy();
}
}
else {
if (window)
Expand All @@ -1422,82 +1407,21 @@ DoStopPlugin(nsPluginInstanceOwner *aInstanceOwner)
inst->SetWindow(nsnull);

inst->Stop();
inst->Destroy();
}
}
else {
if (window)
window->CallSetWindow(nullinst);
else
inst->SetWindow(nsnull);

inst->Stop();
}

nsCOMPtr<nsIPluginHost> pluginHost = do_GetService(kCPluginManagerCID);
if (pluginHost)
pluginHost->StopPluginInstance(inst);

// the frame is going away along with its widget so tell the
// window to forget its widget too
if (window)
window->SetPluginWidget(nsnull);
}

aInstanceOwner->Destroy();
}

NS_IMETHODIMP
nsStopPluginRunnable::Run()
{
DoStopPlugin(mInstanceOwner);

return NS_OK;
}
nsCOMPtr<nsIPluginHost> pluginHost = do_GetService(kCPluginManagerCID);
if (pluginHost)
pluginHost->StopPluginInstance(inst);

void
nsObjectFrame::StopPlugin()
{
StopPluginInternal(PR_FALSE);
}

void
nsObjectFrame::StopPluginInternal(PRBool aDelayedStop)
{
if (mInstanceOwner == nsnull) {
return;
}

mInstanceOwner->PrepareToStop(aDelayedStop);

#ifdef XP_WIN
// We only deal with delayed stopping of plugins on Win32 for now,
// as that's the only platform where we need to (AFAIK) and it's
// unclear how safe widget parenting is on other platforms.
if (aDelayedStop) {
// nsStopPluginRunnable will hold a strong reference to
// mInstanceOwner, and thus keep it alive as long as it needs it.
nsCOMPtr<nsIRunnable> evt = new nsStopPluginRunnable(mInstanceOwner);
NS_DispatchToCurrentThread(evt);

// If we're asked to do a delayed stop it means we're stopping the
// plugin because we're destroying the frame. In that case, tell
// the view to disown the widget (i.e. leave it up to us to
// destroy it).
nsIView *view = GetView();
if (view) {
view->DisownWidget();
// the frame is going away along with its widget
// so tell the window to forget its widget too
if (window)
window->SetPluginWidget(nsnull);
}
} else
#endif
{
DoStopPlugin(mInstanceOwner);
}

// Break relationship between frame and plugin instance owner
mInstanceOwner->SetOwner(nsnull);

NS_RELEASE(mInstanceOwner);
mInstanceOwner->Destroy();
NS_RELEASE(mInstanceOwner);
}
}

void
Expand Down Expand Up @@ -1649,7 +1573,6 @@ nsPluginInstanceOwner::nsPluginInstanceOwner()
mNumCachedParams = 0;
mCachedAttrParamNames = nsnull;
mCachedAttrParamValues = nsnull;
mDestroyWidget = PR_FALSE;
}

nsPluginInstanceOwner::~nsPluginInstanceOwner()
Expand Down Expand Up @@ -3208,45 +3131,6 @@ nsPluginInstanceOwner::Destroy()
target->RemoveEventListener(NS_LITERAL_STRING("draggesture"), listener, PR_TRUE);
}

if (mDestroyWidget && mWidget) {
mWidget->Destroy();
}

return NS_OK;
}

/*
* Prepare to stop
*/
void
nsPluginInstanceOwner::PrepareToStop(PRBool aDelayedStop)
{
if (!mWidget) {
return;
}

#ifdef XP_WIN
if (aDelayedStop) {
// To delay stopping a plugin we need to reparent the plugin to
// the top-level Gecko widget so that we can safely tear down the
// plugin after its frame (and view) is gone.

nsIWidget *appTopWidget = mWidget->GetTopLevelWindow();

// Also hide and disable the widget to avoid it from appearing in
// odd places after reparenting it, but before it gets destroyed.
mWidget->Show(PR_FALSE);
mWidget->Enable(PR_FALSE);

// Reparent the plugins native window. This relies on the widget
// and plugin et al not holding any other references to its
// parent.
mWidget->SetParent(appTopWidget);

mDestroyWidget = PR_TRUE;
}
#endif

// Unregister scroll position listener
nsIFrame* parentWithView = mOwner->GetAncestorWithView();
nsIView* curView = parentWithView ? parentWithView->GetView() : nsnull;
Expand All @@ -3257,6 +3141,10 @@ nsPluginInstanceOwner::PrepareToStop(PRBool aDelayedStop)

curView = curView->GetParent();
}

mOwner = nsnull; // break relationship between frame and plugin instance owner

return NS_OK;
}

// Paints are handled differently, so we just simulate an update event.
Expand Down
8 changes: 0 additions & 8 deletions layout/generic/nsObjectFrame.h
Expand Up @@ -112,14 +112,6 @@ class nsObjectFrame : public nsObjectFrameSuper, public nsIObjectFrame {
virtual nsresult Instantiate(const char* aMimeType, nsIURI* aURI);
virtual void StopPlugin();

/*
* Stop a plugin instance. If aDelayedStop is true, the plugin will
* be stopped at a later point when it's safe to do so (i.e. not
* while destroying the frame tree). Delayed stopping is only
* implemented on Win32 for now.
*/
void StopPluginInternal(PRBool aDelayedStop);


/* fail on any requests to get a cursor from us because plugins set their own! see bug 118877 */
NS_IMETHOD GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor)
Expand Down
9 changes: 0 additions & 9 deletions view/public/nsIView.h
Expand Up @@ -299,14 +299,6 @@ class nsIView
*/
PRBool HasWidget() const { return mWindow != nsnull; }

/**
* If called, will make the view disown the widget and leave it up
* to other code to destroy it.
*/
void DisownWidget() {
mWidgetDisowned = PR_TRUE;
}

#ifdef DEBUG
/**
* Output debug info to FILE
Expand Down Expand Up @@ -337,7 +329,6 @@ class nsIView
nsRect mDimBounds; // relative to parent
float mOpacity;
PRUint32 mVFlags;
PRBool mWidgetDisowned;

virtual ~nsIView() {}
};
Expand Down
5 changes: 1 addition & 4 deletions view/src/nsView.cpp
Expand Up @@ -183,7 +183,6 @@ nsView::nsView(nsViewManager* aViewManager, nsViewVisibility aVisibility)
mVFlags = 0;
mViewManager = aViewManager;
mDirtyRegion = nsnull;
mWidgetDisowned = PR_FALSE;
}

void nsView::DropMouseGrabbing() {
Expand Down Expand Up @@ -251,9 +250,7 @@ nsView::~nsView()
NS_IF_RELEASE(wrapper);

mWindow->SetClientData(nsnull);
if (!mWidgetDisowned) {
mWindow->Destroy();
}
mWindow->Destroy();
NS_RELEASE(mWindow);
}
delete mDirtyRegion;
Expand Down

0 comments on commit 2a009ab

Please sign in to comment.