mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 684938 - Proxy nsXPCWrappedJS::Release to the main thread. r=mrbkap.
--HG-- extra : rebase_source : faf9c46616c52bc03b776a4aae8fd3f87e11f132
This commit is contained in:
parent
610dd20bc3
commit
b63af58931
@ -43,6 +43,7 @@
|
||||
|
||||
#include "xpcprivate.h"
|
||||
#include "nsAtomicRefcnt.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsTextFormatter.h"
|
||||
|
||||
@ -196,6 +197,21 @@ nsXPCWrappedJS::Release(void)
|
||||
{
|
||||
NS_PRECONDITION(0 != mRefCnt, "dup release");
|
||||
|
||||
if (mMainThreadOnly && !NS_IsMainThread()) {
|
||||
// We'd like to abort here, but this can happen if someone uses a proxy
|
||||
// for the nsXPCWrappedJS.
|
||||
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
|
||||
// If we can't get the main thread anymore we just leak, but this really
|
||||
// shouldn't happen.
|
||||
NS_ASSERTION(mainThread,
|
||||
"Can't get main thread, leaking nsXPCWrappedJS!");
|
||||
if (mainThread) {
|
||||
NS_ProxyRelease(mainThread,
|
||||
static_cast<nsIXPConnectWrappedJS*>(this));
|
||||
}
|
||||
return mRefCnt;
|
||||
}
|
||||
|
||||
// need to take the map lock here to prevent GetNewOrUsed from trying
|
||||
// to reuse a wrapper on one thread while it's being destroyed on another
|
||||
XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
|
||||
@ -264,6 +280,28 @@ nsXPCWrappedJS::GetJSObject(JSObject** aJSObj)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static bool
|
||||
CheckMainThreadOnly(nsXPCWrappedJS *aWrapper)
|
||||
{
|
||||
if(aWrapper->IsMainThreadOnly())
|
||||
return NS_IsMainThread();
|
||||
|
||||
nsCOMPtr<nsIClassInfo> ci;
|
||||
CallQueryInterface(aWrapper, getter_AddRefs(ci));
|
||||
if (ci) {
|
||||
PRUint32 flags;
|
||||
if (NS_SUCCEEDED(ci->GetFlags(&flags)) && !(flags & nsIClassInfo::MAIN_THREAD_ONLY))
|
||||
return true;
|
||||
|
||||
if (!NS_IsMainThread())
|
||||
return false;
|
||||
}
|
||||
|
||||
aWrapper->SetIsMainThreadOnly();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
nsXPCWrappedJS::GetNewOrUsed(XPCCallContext& ccx,
|
||||
@ -317,7 +355,9 @@ nsXPCWrappedJS::GetNewOrUsed(XPCCallContext& ccx,
|
||||
// the root will do double duty as the interface wrapper
|
||||
wrapper = root = new nsXPCWrappedJS(ccx, aJSObj, clazz, nsnull,
|
||||
aOuter);
|
||||
if (root)
|
||||
if (!root)
|
||||
goto return_wrapper;
|
||||
|
||||
{ // scoped lock
|
||||
#if DEBUG_xpc_leaks
|
||||
printf("Created nsXPCWrappedJS %p, JSObject is %p\n",
|
||||
@ -326,6 +366,14 @@ nsXPCWrappedJS::GetNewOrUsed(XPCCallContext& ccx,
|
||||
XPCAutoLock lock(rt->GetMapLock());
|
||||
map->Add(root);
|
||||
}
|
||||
|
||||
if (!CheckMainThreadOnly(root)) {
|
||||
XPCAutoLock lock(rt->GetMapLock());
|
||||
map->Remove(root);
|
||||
|
||||
wrapper = NULL;
|
||||
}
|
||||
|
||||
goto return_wrapper;
|
||||
} else {
|
||||
// just a root wrapper
|
||||
@ -351,6 +399,13 @@ nsXPCWrappedJS::GetNewOrUsed(XPCCallContext& ccx,
|
||||
XPCAutoLock lock(rt->GetMapLock());
|
||||
map->Add(root);
|
||||
}
|
||||
|
||||
if (!CheckMainThreadOnly(root)) {
|
||||
XPCAutoLock lock(rt->GetMapLock());
|
||||
map->Remove(root);
|
||||
|
||||
goto return_wrapper;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -395,7 +450,8 @@ nsXPCWrappedJS::nsXPCWrappedJS(XPCCallContext& ccx,
|
||||
mRoot(root ? root : this),
|
||||
mNext(nsnull),
|
||||
mOuter(root ? nsnull : aOuter),
|
||||
mMainThread(NS_IsMainThread())
|
||||
mMainThread(NS_IsMainThread()),
|
||||
mMainThreadOnly(root && root->mMainThreadOnly)
|
||||
{
|
||||
#ifdef DEBUG_stats_jband
|
||||
static int count = 0;
|
||||
@ -404,6 +460,8 @@ nsXPCWrappedJS::nsXPCWrappedJS(XPCCallContext& ccx,
|
||||
printf("//////// %d instances of nsXPCWrappedJS created\n", count);
|
||||
#endif
|
||||
|
||||
JS_ASSERT_IF(mMainThreadOnly, mMainThread);
|
||||
|
||||
InitStub(GetClass()->GetIID());
|
||||
|
||||
// intentionally do double addref - see Release().
|
||||
|
@ -3036,6 +3036,9 @@ public:
|
||||
JSBool IsAggregatedToNative() const {return mRoot->mOuter != nsnull;}
|
||||
nsISupports* GetAggregatedNativeObject() const {return mRoot->mOuter;}
|
||||
|
||||
void SetIsMainThreadOnly() {JS_ASSERT(mMainThread); mMainThreadOnly = true;}
|
||||
bool IsMainThreadOnly() const {return mMainThreadOnly;}
|
||||
|
||||
void TraceJS(JSTracer* trc);
|
||||
#ifdef DEBUG
|
||||
static void PrintTraceName(JSTracer* trc, char *buf, size_t bufsize);
|
||||
@ -3059,6 +3062,7 @@ private:
|
||||
nsXPCWrappedJS* mNext;
|
||||
nsISupports* mOuter; // only set in root
|
||||
bool mMainThread;
|
||||
bool mMainThreadOnly;
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
Loading…
Reference in New Issue
Block a user