mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-16 22:04:36 +00:00
Make sure that we push a null JSContext on the current thread's XPConnect stack
before processing events. Bug 326777, r=bsmedberg, sr=jst
This commit is contained in:
parent
b6a07ae185
commit
30e205dddb
@ -50,8 +50,12 @@
|
|||||||
#include "jsfun.h"
|
#include "jsfun.h"
|
||||||
#include "jsobj.h"
|
#include "jsobj.h"
|
||||||
#include "jsscript.h"
|
#include "jsscript.h"
|
||||||
|
#include "nsThreadUtilsInternal.h"
|
||||||
|
|
||||||
NS_IMPL_THREADSAFE_ISUPPORTS2(nsXPConnect,nsIXPConnect,nsISupportsWeakReference)
|
NS_IMPL_THREADSAFE_ISUPPORTS3(nsXPConnect,
|
||||||
|
nsIXPConnect,
|
||||||
|
nsISupportsWeakReference,
|
||||||
|
nsIThreadObserver)
|
||||||
|
|
||||||
nsXPConnect* nsXPConnect::gSelf = nsnull;
|
nsXPConnect* nsXPConnect::gSelf = nsnull;
|
||||||
JSBool nsXPConnect::gOnceAliveNowDead = JS_FALSE;
|
JSBool nsXPConnect::gOnceAliveNowDead = JS_FALSE;
|
||||||
@ -286,6 +290,10 @@ nsXPConnect::GetXPConnect()
|
|||||||
// Initial extra ref to keep the singleton alive
|
// Initial extra ref to keep the singleton alive
|
||||||
// balanced by explicit call to ReleaseXPConnectSingleton()
|
// balanced by explicit call to ReleaseXPConnectSingleton()
|
||||||
NS_ADDREF(gSelf);
|
NS_ADDREF(gSelf);
|
||||||
|
if (NS_FAILED(NS_SetGlobalThreadObserver(gSelf))) {
|
||||||
|
NS_RELEASE(gSelf);
|
||||||
|
// Fall through to returning null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return gSelf;
|
return gSelf;
|
||||||
@ -307,6 +315,7 @@ nsXPConnect::ReleaseXPConnectSingleton()
|
|||||||
nsXPConnect* xpc = gSelf;
|
nsXPConnect* xpc = gSelf;
|
||||||
if(xpc)
|
if(xpc)
|
||||||
{
|
{
|
||||||
|
NS_SetGlobalThreadObserver(nsnull);
|
||||||
|
|
||||||
#ifdef XPC_TOOLS_SUPPORT
|
#ifdef XPC_TOOLS_SUPPORT
|
||||||
if(xpc->mProfiler)
|
if(xpc->mProfiler)
|
||||||
@ -2014,6 +2023,31 @@ nsXPConnect::FlagSystemFilenamePrefix(const char *aFilenamePrefix)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXPConnect::OnProcessNextEvent(nsIThreadInternal *aThread, PRBool aMayWait,
|
||||||
|
PRUint32 aRecursionDepth)
|
||||||
|
{
|
||||||
|
// Push a null JSContext so that we don't see any script during
|
||||||
|
// event processing.
|
||||||
|
NS_ENSURE_STATE(mContextStack);
|
||||||
|
return mContextStack->Push(nsnull);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXPConnect::AfterProcessNextEvent(nsIThreadInternal *aThread,
|
||||||
|
PRUint32 aRecursionDepth)
|
||||||
|
{
|
||||||
|
NS_ENSURE_STATE(mContextStack);
|
||||||
|
return mContextStack->Pop(nsnull);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXPConnect::OnDispatchedEvent(nsIThreadInternal* aThread)
|
||||||
|
{
|
||||||
|
NS_NOTREACHED("Why tell us?");
|
||||||
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/* These are here to be callable from a debugger */
|
/* These are here to be callable from a debugger */
|
||||||
JS_BEGIN_EXTERN_C
|
JS_BEGIN_EXTERN_C
|
||||||
|
@ -126,6 +126,8 @@
|
|||||||
#include "nsIXPCToolsProfiler.h"
|
#include "nsIXPCToolsProfiler.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "nsIThreadInternal.h"
|
||||||
|
|
||||||
#ifdef XPC_IDISPATCH_SUPPORT
|
#ifdef XPC_IDISPATCH_SUPPORT
|
||||||
// This goop was added because of EXCEPINFO in ThrowCOMError
|
// This goop was added because of EXCEPINFO in ThrowCOMError
|
||||||
// This include is here, because it needs to occur before the undefines below
|
// This include is here, because it needs to occur before the undefines below
|
||||||
@ -426,6 +428,7 @@ const PRBool OBJ_IS_NOT_GLOBAL = PR_FALSE;
|
|||||||
struct JSObjectRefcounts;
|
struct JSObjectRefcounts;
|
||||||
|
|
||||||
class nsXPConnect : public nsIXPConnect,
|
class nsXPConnect : public nsIXPConnect,
|
||||||
|
public nsIThreadObserver,
|
||||||
public nsSupportsWeakReference,
|
public nsSupportsWeakReference,
|
||||||
public nsCycleCollectionLanguageRuntime,
|
public nsCycleCollectionLanguageRuntime,
|
||||||
public nsCycleCollectionParticipant
|
public nsCycleCollectionParticipant
|
||||||
@ -434,6 +437,7 @@ public:
|
|||||||
// all the interface method declarations...
|
// all the interface method declarations...
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSIXPCONNECT
|
NS_DECL_NSIXPCONNECT
|
||||||
|
NS_DECL_NSITHREADOBSERVER
|
||||||
|
|
||||||
// non-interface implementation
|
// non-interface implementation
|
||||||
public:
|
public:
|
||||||
|
@ -69,6 +69,7 @@ CPPSRCS = \
|
|||||||
EXPORTS = \
|
EXPORTS = \
|
||||||
nsProcess.h \
|
nsProcess.h \
|
||||||
nsEventQueue.h \
|
nsEventQueue.h \
|
||||||
|
nsThreadUtilsInternal.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
XPIDLSRCS = \
|
XPIDLSRCS = \
|
||||||
|
@ -52,6 +52,8 @@ static PRLogModuleInfo *sLog = PR_NewLogModule("nsThread");
|
|||||||
|
|
||||||
NS_DECL_CI_INTERFACE_GETTER(nsThread)
|
NS_DECL_CI_INTERFACE_GETTER(nsThread)
|
||||||
|
|
||||||
|
nsIThreadObserver* nsThread::sGlobalObserver;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Because we do not have our own nsIFactory, we have to implement nsIClassInfo
|
// Because we do not have our own nsIFactory, we have to implement nsIClassInfo
|
||||||
// somewhat manually.
|
// somewhat manually.
|
||||||
@ -464,6 +466,10 @@ nsThread::ProcessNextEvent(PRBool mayWait, PRBool *result)
|
|||||||
|
|
||||||
NS_ENSURE_STATE(PR_GetCurrentThread() == mThread);
|
NS_ENSURE_STATE(PR_GetCurrentThread() == mThread);
|
||||||
|
|
||||||
|
if (sGlobalObserver)
|
||||||
|
sGlobalObserver->OnProcessNextEvent(this, mayWait && !ShuttingDown(),
|
||||||
|
mRunningEvent);
|
||||||
|
|
||||||
nsCOMPtr<nsIThreadObserver> obs = mObserver;
|
nsCOMPtr<nsIThreadObserver> obs = mObserver;
|
||||||
if (obs)
|
if (obs)
|
||||||
obs->OnProcessNextEvent(this, mayWait && !ShuttingDown(), mRunningEvent);
|
obs->OnProcessNextEvent(this, mayWait && !ShuttingDown(), mRunningEvent);
|
||||||
@ -489,6 +495,9 @@ nsThread::ProcessNextEvent(PRBool mayWait, PRBool *result)
|
|||||||
if (obs)
|
if (obs)
|
||||||
obs->AfterProcessNextEvent(this, mRunningEvent);
|
obs->AfterProcessNextEvent(this, mRunningEvent);
|
||||||
|
|
||||||
|
if (sGlobalObserver)
|
||||||
|
sGlobalObserver->AfterProcessNextEvent(this, mRunningEvent);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -618,3 +627,18 @@ nsThreadSyncDispatch::Run()
|
|||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
NS_SetGlobalThreadObserver(nsIThreadObserver* aObserver)
|
||||||
|
{
|
||||||
|
if (aObserver && nsThread::sGlobalObserver) {
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NS_IsMainThread()) {
|
||||||
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsThread::sGlobalObserver = aObserver;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
@ -72,6 +72,9 @@ public:
|
|||||||
// nsIThreadManager::NewThread.
|
// nsIThreadManager::NewThread.
|
||||||
PRBool ShutdownRequired() { return mShutdownRequired; }
|
PRBool ShutdownRequired() { return mShutdownRequired; }
|
||||||
|
|
||||||
|
// The global thread observer
|
||||||
|
static nsIThreadObserver* sGlobalObserver;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class nsThreadShutdownEvent;
|
friend class nsThreadShutdownEvent;
|
||||||
|
|
||||||
|
61
xpcom/threads/nsThreadUtilsInternal.h
Normal file
61
xpcom/threads/nsThreadUtilsInternal.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is the Mozilla Corporation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Boris Zbarsky <bzbarsky@mit.edu>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#ifndef nsThreadUtilsInternal_h_
|
||||||
|
#define nsThreadUtilsInternal_h_
|
||||||
|
|
||||||
|
#ifdef MOZILLA_INTERNAL_API
|
||||||
|
|
||||||
|
class nsIThreadObserver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to set a "global" thread observer that all threads will notify when
|
||||||
|
* they process an event. This observer will not be notified when events are
|
||||||
|
* posted to threads. Only one global observer can be set at a time; an
|
||||||
|
* attempt to change the value without setting it to null first will throw.
|
||||||
|
* This function does NOT take a reference to the observer; the caller of this
|
||||||
|
* function is responsible for setting the observer to null when it goes away.
|
||||||
|
* This method may only be called on the main thread; attempts to do it on
|
||||||
|
* other threads will return an error.
|
||||||
|
*/
|
||||||
|
extern nsresult
|
||||||
|
NS_COM NS_SetGlobalThreadObserver(nsIThreadObserver* aObserver);
|
||||||
|
|
||||||
|
#endif // MOZILLA_INTERNAL_API
|
||||||
|
|
||||||
|
#endif // nsThreadUtilsInternal_h_
|
Loading…
x
Reference in New Issue
Block a user