зеркало из https://github.com/mozilla/gecko-dev.git
Bug 475347: Crash after closing tab that initiated an install and included a callback function. r+sr=dveditz
This commit is contained in:
Родитель
1c9edc6eff
Коммит
6dbd3cbf99
|
@ -196,20 +196,15 @@ nsXPITriggerInfo::~nsXPITriggerInfo()
|
|||
void nsXPITriggerInfo::SaveCallback( JSContext *aCx, jsval aVal )
|
||||
{
|
||||
NS_ASSERTION( mCx == 0, "callback set twice, memory leak" );
|
||||
// We'll only retain the callback if we can get a strong reference to the
|
||||
// context.
|
||||
if (!(JS_GetOptions(aCx) & JSOPTION_PRIVATE_IS_NSISUPPORTS))
|
||||
return;
|
||||
mContextWrapper = static_cast<nsISupports *>(JS_GetContextPrivate(aCx));
|
||||
if (!mContextWrapper)
|
||||
return;
|
||||
|
||||
mCx = aCx;
|
||||
JSObject *obj = JS_GetGlobalObject( mCx );
|
||||
|
||||
JSClass* clazz;
|
||||
|
||||
clazz = ::JS_GET_CLASS(aCx, obj);
|
||||
|
||||
if (clazz &&
|
||||
(clazz->flags & JSCLASS_HAS_PRIVATE) &&
|
||||
(clazz->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS)) {
|
||||
mGlobalWrapper =
|
||||
do_QueryInterface((nsISupports*)::JS_GetPrivate(aCx, obj));
|
||||
}
|
||||
|
||||
mCbval = aVal;
|
||||
mThread = do_GetCurrentThread();
|
||||
|
||||
|
@ -232,12 +227,21 @@ XPITriggerEvent::Run()
|
|||
{
|
||||
jsval ret;
|
||||
void* mark;
|
||||
jsval* args;
|
||||
jsval* args = nsnull;
|
||||
|
||||
JS_BeginRequest(cx);
|
||||
args = JS_PushArguments(cx, &mark, "Wi",
|
||||
URL.get(),
|
||||
status);
|
||||
|
||||
// If Components doesn't exist in the global object then XPConnect has
|
||||
// been torn down, probably because the page was closed. Bail out if that
|
||||
// is the case.
|
||||
JSObject* innerGlobal = JS_GetGlobalForObject(cx, JSVAL_TO_OBJECT(cbval));
|
||||
jsval components;
|
||||
if (JS_LookupProperty(cx, innerGlobal, "Components", &components) &&
|
||||
JSVAL_IS_OBJECT(components))
|
||||
{
|
||||
args = JS_PushArguments(cx, &mark, "Wi", URL.get(), status);
|
||||
}
|
||||
|
||||
if ( args )
|
||||
{
|
||||
// This code is all in a JS request, and here we're about to
|
||||
|
@ -288,7 +292,7 @@ XPITriggerEvent::Run()
|
|||
else
|
||||
{
|
||||
JS_CallFunctionValue(cx,
|
||||
JSVAL_TO_OBJECT(global),
|
||||
JS_GetGlobalObject(cx),
|
||||
cbval,
|
||||
2,
|
||||
args,
|
||||
|
@ -310,7 +314,7 @@ void nsXPITriggerInfo::SendStatus(const PRUnichar* URL, PRInt32 status)
|
|||
{
|
||||
nsresult rv;
|
||||
|
||||
if ( mCx && mGlobalWrapper && !JSVAL_IS_NULL(mCbval) )
|
||||
if ( mCx && mContextWrapper && !JSVAL_IS_NULL(mCbval) )
|
||||
{
|
||||
// create event and post it
|
||||
nsRefPtr<XPITriggerEvent> event = new XPITriggerEvent();
|
||||
|
@ -321,12 +325,6 @@ void nsXPITriggerInfo::SendStatus(const PRUnichar* URL, PRInt32 status)
|
|||
event->cx = mCx;
|
||||
event->princ = mPrincipal;
|
||||
|
||||
JSObject *obj = nsnull;
|
||||
|
||||
mGlobalWrapper->GetJSObject(&obj);
|
||||
|
||||
event->global = OBJECT_TO_JSVAL(obj);
|
||||
|
||||
event->cbval = mCbval;
|
||||
JS_BeginRequest(event->cx);
|
||||
JS_AddNamedRoot(event->cx, &event->cbval,
|
||||
|
@ -335,7 +333,7 @@ void nsXPITriggerInfo::SendStatus(const PRUnichar* URL, PRInt32 status)
|
|||
|
||||
// Hold a strong reference to keep the underlying
|
||||
// JSContext from dying before we handle this event.
|
||||
event->ref = mGlobalWrapper;
|
||||
event->ref = mContextWrapper;
|
||||
|
||||
rv = mThread->Dispatch(event, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
|
|
@ -57,7 +57,6 @@ struct XPITriggerEvent : public nsRunnable {
|
|||
nsString URL;
|
||||
PRInt32 status;
|
||||
JSContext* cx;
|
||||
jsval global;
|
||||
jsval cbval;
|
||||
nsCOMPtr<nsISupports> ref;
|
||||
nsCOMPtr<nsIPrincipal> princ;
|
||||
|
@ -131,7 +130,7 @@ class nsXPITriggerInfo
|
|||
private:
|
||||
nsVoidArray mItems;
|
||||
JSContext *mCx;
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> mGlobalWrapper;
|
||||
nsCOMPtr<nsISupports> mContextWrapper;
|
||||
jsval mCbval;
|
||||
nsCOMPtr<nsIThread> mThread;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче