From 238a849b3f62d8f3c0e93343b3a82a5f84d6cb1c Mon Sep 17 00:00:00 2001 From: "jband%netscape.com" Date: Tue, 19 Sep 2000 01:09:48 +0000 Subject: [PATCH] fix shutdown crasher bug 52940. We can't leave the thread context stack service thinking that the context we are about to delete is still valid. a,r=brendan@mozilla.org git-svn-id: svn://10.0.0.236/trunk@79495 18797224-902f-48f8-a5cc-f745e15eee43 --- .../js/src/xpconnect/src/xpcthreadcontext.cpp | 10 ++-- .../xpfe/appshell/src/nsAppShellService.cpp | 51 +++++++++++++++---- mozilla/xpfe/appshell/src/nsAppShellService.h | 2 + 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/mozilla/js/src/xpconnect/src/xpcthreadcontext.cpp b/mozilla/js/src/xpconnect/src/xpcthreadcontext.cpp index 4246a9e2a46..eb7dcc7f0d9 100644 --- a/mozilla/js/src/xpconnect/src/xpcthreadcontext.cpp +++ b/mozilla/js/src/xpconnect/src/xpcthreadcontext.cpp @@ -336,10 +336,14 @@ xpcPerThreadData::GetSafeJSContext() nsresult xpcPerThreadData::SetSafeJSContext(JSContext *cx) { - NS_ASSERTION(cx, "SetSafeJSContext called with a null context"); + if(mOwnSafeJSContext && + mOwnSafeJSContext == mSafeJSContext && + mOwnSafeJSContext != cx) + { + JS_DestroyContext(mOwnSafeJSContext); + mOwnSafeJSContext = nsnull; + } - if(!cx) - return NS_ERROR_INVALID_ARG; mSafeJSContext = cx; return NS_OK; } diff --git a/mozilla/xpfe/appshell/src/nsAppShellService.cpp b/mozilla/xpfe/appshell/src/nsAppShellService.cpp index b812d12a697..07d22346eaa 100644 --- a/mozilla/xpfe/appshell/src/nsAppShellService.cpp +++ b/mozilla/xpfe/appshell/src/nsAppShellService.cpp @@ -35,6 +35,7 @@ #include "nsWeakReference.h" #include "nsXPComFactory.h" /* template implementation of a XPCOM factory */ #include "nsIXPConnect.h" +#include "nsIJSContextStack.h" #include "nsIAppShell.h" #include "nsIWidget.h" @@ -92,8 +93,10 @@ nsAppShellService::~nsAppShellService() { mDeleteCalled = PR_TRUE; nsCOMPtr hiddenWin(do_QueryInterface(mHiddenWindow)); - if(hiddenWin) + if(hiddenWin) { + ClearXPConnectSafeContext(); hiddenWin->Close(); + } /* Note we don't unregister with the observer service (RegisterObserver(PR_FALSE)) because, being refcounted, we can't have reached our own destructor until after the ObserverService has shut down @@ -177,7 +180,40 @@ done: return rv; } +nsresult +nsAppShellService::SetXPConnectSafeContext() +{ + nsresult rv; + NS_WITH_SERVICE(nsIXPConnect, xpc, kXPConnectCID, &rv); + if (NS_FAILED(rv)) return rv; + nsCOMPtr junk; + JSContext *cx; + rv = GetHiddenWindowAndJSContext(getter_AddRefs(junk), &cx); + if (NS_FAILED(rv)) return rv; + rv = xpc->SetSafeJSContextForCurrentThread(cx); + return rv; +} +nsresult nsAppShellService::ClearXPConnectSafeContext() +{ + nsresult rv; + NS_WITH_SERVICE(nsIXPConnect, xpc, kXPConnectCID, &rv); + if (NS_FAILED(rv)) return rv; + nsCOMPtr junk; + JSContext *cx; + rv = GetHiddenWindowAndJSContext(getter_AddRefs(junk), &cx); + if (NS_FAILED(rv)) return rv; + + NS_WITH_SERVICE(nsIThreadJSContextStack, cxstack, + "@mozilla.org/js/xpc/ContextStack;1", &rv); + if (NS_FAILED(rv)) return rv; + JSContext *safe_cx; + rv = cxstack->GetSafeJSContext(&safe_cx); + if (NS_FAILED(rv)) return rv; + if (cx == safe_cx) + rv = xpc->SetSafeJSContextForCurrentThread(nsnull); + return rv; +} NS_IMETHODIMP nsAppShellService::CreateHiddenWindow() @@ -208,14 +244,7 @@ nsAppShellService::CreateHiddenWindow() // to the DOM JSContext for this thread, so that DOM-to-XPConnect // conversions get the JSContext private magic they need to // succeed. - NS_WITH_SERVICE(nsIXPConnect, xpc, kXPConnectCID, &rv); - if (NS_FAILED(rv)) return rv; - nsCOMPtr junk; - JSContext *cx; - rv = GetHiddenWindowAndJSContext(getter_AddRefs(junk), &cx); - if (NS_FAILED(rv)) return rv; - rv = xpc->SetSafeJSContextForCurrentThread(cx); - if (NS_FAILED(rv)) return rv; + SetXPConnectSafeContext(); // RegisterTopLevelWindow(newWindow); -- Mac only } @@ -420,8 +449,10 @@ nsAppShellService::Quit() { nsCOMPtr hiddenWin(do_QueryInterface(mHiddenWindow)); - if (hiddenWin) + if (hiddenWin) { + ClearXPConnectSafeContext(); hiddenWin->Close(); + } mHiddenWindow = nsnull; } diff --git a/mozilla/xpfe/appshell/src/nsAppShellService.h b/mozilla/xpfe/appshell/src/nsAppShellService.h index bc216d3d96b..282210f50d5 100644 --- a/mozilla/xpfe/appshell/src/nsAppShellService.h +++ b/mozilla/xpfe/appshell/src/nsAppShellService.h @@ -58,6 +58,8 @@ protected: void ShutdownComponent( const nsCID &aComponentCID ); typedef void (nsAppShellService::*EnumeratorMemberFunction)(const nsCID&); void EnumerateComponents( void (nsAppShellService::*function)(const nsCID&) ); + nsresult SetXPConnectSafeContext(); + nsresult ClearXPConnectSafeContext(); nsCOMPtr mAppShell; nsCOMPtr mWindowList;