// static void XPCWrappedNativeScope::SweepAllWrappedNativeTearOffs() { for (XPCWrappedNativeScope* cur = gScopes; cur; cur = cur->mNext) cur->mWrappedNativeMap->Enumerate(WrappedNativeTearoffSweeper, nsnull); DEBUG_TrackScopeTraversal(); }
//static void XPCWrappedNativeScope::SystemIsBeingShutDown(JSContext* cx) { DEBUG_TrackScopeTraversal(); DEBUG_TrackScopeShutdown(); int liveScopeCount = 0; ShutdownData data(cx); XPCWrappedNativeScope* cur; // First move all the scopes to the dying list. cur = gScopes; while(cur) { XPCWrappedNativeScope* next = cur->mNext; cur->mNext = gDyingScopes; gDyingScopes = cur; cur = next; liveScopeCount++; } gScopes = nsnull; // Walk the unified dying list and call shutdown on all wrappers and protos for(cur = gDyingScopes; cur; cur = cur->mNext) { // Give the Components object a chance to try to clean up. if(cur->mComponents) cur->mComponents->SystemIsBeingShutDown(); // Walk the protos first. Wrapper shutdown can leave dangling // proto pointers in the proto map. cur->mWrappedNativeProtoMap-> Enumerate(WrappedNativeProtoShutdownEnumerator, &data); cur->mWrappedNativeMap-> Enumerate(WrappedNativeShutdownEnumerator, &data); } // Now it is safe to kill all the scopes. KillDyingScopes(); #ifdef XPC_DUMP_AT_SHUTDOWN if(data.wrapperCount) printf("deleting nsXPConnect with %d live XPCWrappedNatives\n", data.wrapperCount); if(data.sharedProtoCount + data.nonSharedProtoCount) printf("deleting nsXPConnect with %d live XPCWrappedNativeProtos (%d shared)\n", data.sharedProtoCount + data.nonSharedProtoCount, data.sharedProtoCount); if(liveScopeCount) printf("deleting nsXPConnect with %d live XPCWrappedNativeScopes\n", liveScopeCount); #endif }
// static void XPCWrappedNativeScope::MarkAllWrappedNativesAndProtos() { for (XPCWrappedNativeScope* cur = gScopes; cur; cur = cur->mNext) { cur->mWrappedNativeMap->Enumerate(WrappedNativeMarker, nsnull); cur->mWrappedNativeProtoMap->Enumerate(WrappedNativeProtoMarker, nsnull); cur->mMainThreadWrappedNativeProtoMap->Enumerate(WrappedNativeProtoMarker, nsnull); } DEBUG_TrackScopeTraversal(); }
// static XPCWrappedNativeScope* XPCWrappedNativeScope::FindInJSObjectScope(JSContext* cx, JSObject* obj, JSBool OKIfNotInitialized, XPCJSRuntime* runtime) { XPCWrappedNativeScope* scope; if(!obj) return nsnull; // If this object is itself a wrapped native then we can get the // scope directly. scope = GetScopeOfObject(obj); if(scope) return scope; // Else we'll have to look up the parent chain to get the scope obj = JS_GetGlobalForObject(cx, obj); if(!runtime) { runtime = nsXPConnect::GetRuntime(); if(!runtime) return nsnull; } // XXX We are assuming that the scope count is low enough that traversing // the linked list is more reasonable then doing a hashtable lookup. { // scoped lock XPCAutoLock lock(runtime->GetMapLock()); DEBUG_TrackScopeTraversal(); for(XPCWrappedNativeScope* cur = gScopes; cur; cur = cur->mNext) { if(obj == cur->GetGlobalJSObject()) { DEBUG_CheckForComponentsInScope(cx, obj, OKIfNotInitialized, runtime); return cur; } } } // Failure to find the scope is only OK if the caller told us it might fail. // This flag would only be set in the call from // XPCWrappedNativeScope::GetNewOrUsed NS_ASSERTION(OKIfNotInitialized, "No scope has this global object!"); return nsnull; }
// static nsresult XPCWrappedNativeScope::ClearAllWrappedNativeSecurityPolicies(XPCCallContext& ccx) { // Hold the lock throughout. XPCAutoLock lock(ccx.GetRuntime()->GetMapLock()); for (XPCWrappedNativeScope* cur = gScopes; cur; cur = cur->mNext) { cur->mWrappedNativeProtoMap->Enumerate(WNProtoSecPolicyClearer, nsnull); cur->mMainThreadWrappedNativeProtoMap->Enumerate(WNProtoSecPolicyClearer, nsnull); } DEBUG_TrackScopeTraversal(); return NS_OK; }
// static XPCWrappedNativeScope* XPCWrappedNativeScope::FindInJSObjectScope(JSContext* cx, JSObject* obj, JSBool OKIfNotInitialized, XPCJSRuntime* runtime) { XPCWrappedNativeScope* scope; if (!obj) return nsnull; // If this object is itself a wrapped native then we can get the // scope directly. scope = GetScopeOfObject(obj); if (scope) return scope; // Else we'll have to look up the parent chain to get the scope JSAutoEnterCompartment ac; ac.enterAndIgnoreErrors(cx, obj); #ifdef DEBUG JSObject *startingObj = obj; #endif obj = JS_GetGlobalForObject(cx, obj); if (js::GetObjectClass(obj)->flags & JSCLASS_XPCONNECT_GLOBAL) { scope = XPCWrappedNativeScope::GetNativeScope(cx, obj); if (scope) return scope; } if (!runtime) { runtime = nsXPConnect::GetRuntimeInstance(); NS_ASSERTION(runtime, "This should never be null!"); } // XXX We are assuming that the scope count is low enough that traversing // the linked list is more reasonable then doing a hashtable lookup. XPCWrappedNativeScope* found = nsnull; { // scoped lock XPCAutoLock lock(runtime->GetMapLock()); DEBUG_TrackScopeTraversal(); for (XPCWrappedNativeScope* cur = gScopes; cur; cur = cur->mNext) { if (obj == cur->GetGlobalJSObject()) { found = cur; break; } } } if (found) { // This cannot be called within the map lock! DEBUG_CheckForComponentsInScope(cx, obj, startingObj, OKIfNotInitialized, runtime); return found; } // Failure to find the scope is only OK if the caller told us it might fail. // This flag would only be set in the call from // XPCWrappedNativeScope::GetNewOrUsed NS_ASSERTION(OKIfNotInitialized, "No scope has this global object!"); return nsnull; }