mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +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 "jsobj.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;
|
||||
JSBool nsXPConnect::gOnceAliveNowDead = JS_FALSE;
|
||||
@ -286,6 +290,10 @@ nsXPConnect::GetXPConnect()
|
||||
// Initial extra ref to keep the singleton alive
|
||||
// balanced by explicit call to ReleaseXPConnectSingleton()
|
||||
NS_ADDREF(gSelf);
|
||||
if (NS_FAILED(NS_SetGlobalThreadObserver(gSelf))) {
|
||||
NS_RELEASE(gSelf);
|
||||
// Fall through to returning null
|
||||
}
|
||||
}
|
||||
}
|
||||
return gSelf;
|
||||
@ -307,6 +315,7 @@ nsXPConnect::ReleaseXPConnectSingleton()
|
||||
nsXPConnect* xpc = gSelf;
|
||||
if(xpc)
|
||||
{
|
||||
NS_SetGlobalThreadObserver(nsnull);
|
||||
|
||||
#ifdef XPC_TOOLS_SUPPORT
|
||||
if(xpc->mProfiler)
|
||||
@ -2014,6 +2023,31 @@ nsXPConnect::FlagSystemFilenamePrefix(const char *aFilenamePrefix)
|
||||
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
|
||||
/* These are here to be callable from a debugger */
|
||||
JS_BEGIN_EXTERN_C
|
||||
|
@ -126,6 +126,8 @@
|
||||
#include "nsIXPCToolsProfiler.h"
|
||||
#endif
|
||||
|
||||
#include "nsIThreadInternal.h"
|
||||
|
||||
#ifdef XPC_IDISPATCH_SUPPORT
|
||||
// This goop was added because of EXCEPINFO in ThrowCOMError
|
||||
// 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;
|
||||
|
||||
class nsXPConnect : public nsIXPConnect,
|
||||
public nsIThreadObserver,
|
||||
public nsSupportsWeakReference,
|
||||
public nsCycleCollectionLanguageRuntime,
|
||||
public nsCycleCollectionParticipant
|
||||
@ -434,6 +437,7 @@ public:
|
||||
// all the interface method declarations...
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIXPCONNECT
|
||||
NS_DECL_NSITHREADOBSERVER
|
||||
|
||||
// non-interface implementation
|
||||
public:
|
||||
|
@ -69,6 +69,7 @@ CPPSRCS = \
|
||||
EXPORTS = \
|
||||
nsProcess.h \
|
||||
nsEventQueue.h \
|
||||
nsThreadUtilsInternal.h \
|
||||
$(NULL)
|
||||
|
||||
XPIDLSRCS = \
|
||||
|
@ -52,6 +52,8 @@ static PRLogModuleInfo *sLog = PR_NewLogModule("nsThread");
|
||||
|
||||
NS_DECL_CI_INTERFACE_GETTER(nsThread)
|
||||
|
||||
nsIThreadObserver* nsThread::sGlobalObserver;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Because we do not have our own nsIFactory, we have to implement nsIClassInfo
|
||||
// somewhat manually.
|
||||
@ -464,6 +466,10 @@ nsThread::ProcessNextEvent(PRBool mayWait, PRBool *result)
|
||||
|
||||
NS_ENSURE_STATE(PR_GetCurrentThread() == mThread);
|
||||
|
||||
if (sGlobalObserver)
|
||||
sGlobalObserver->OnProcessNextEvent(this, mayWait && !ShuttingDown(),
|
||||
mRunningEvent);
|
||||
|
||||
nsCOMPtr<nsIThreadObserver> obs = mObserver;
|
||||
if (obs)
|
||||
obs->OnProcessNextEvent(this, mayWait && !ShuttingDown(), mRunningEvent);
|
||||
@ -489,6 +495,9 @@ nsThread::ProcessNextEvent(PRBool mayWait, PRBool *result)
|
||||
if (obs)
|
||||
obs->AfterProcessNextEvent(this, mRunningEvent);
|
||||
|
||||
if (sGlobalObserver)
|
||||
sGlobalObserver->AfterProcessNextEvent(this, mRunningEvent);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -618,3 +627,18 @@ nsThreadSyncDispatch::Run()
|
||||
}
|
||||
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.
|
||||
PRBool ShutdownRequired() { return mShutdownRequired; }
|
||||
|
||||
// The global thread observer
|
||||
static nsIThreadObserver* sGlobalObserver;
|
||||
|
||||
private:
|
||||
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…
Reference in New Issue
Block a user