Bug 1166592 - Remove ParentIdleListener from idle service when ActorDestroy() to avoid leaking ContentParent. r=khuey

This commit is contained in:
Ting-Yu Chou 2015-05-27 16:05:04 +08:00
parent cb2e2f1b8d
commit 6275f56f8d
2 changed files with 33 additions and 17 deletions

View File

@ -2035,6 +2035,15 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
obs->NotifyObservers((nsIPropertyBag2*) props, "ipc:content-shutdown", nullptr);
}
// Remove any and all idle listeners.
nsCOMPtr<nsIIdleService> idleService =
do_GetService("@mozilla.org/widget/idleservice;1");
MOZ_ASSERT(idleService);
nsRefPtr<ParentIdleListener> listener;
for (int32_t i = mIdleListeners.Length() - 1; i >= 0; --i) {
listener = static_cast<ParentIdleListener*>(mIdleListeners[i].get());
idleService->RemoveIdleObserver(listener, listener->mTime);
}
mIdleListeners.Clear();
MessageLoop::current()->
@ -4660,30 +4669,34 @@ ContentParent::RecvAddIdleObserver(const uint64_t& aObserver, const uint32_t& aI
{
nsresult rv;
nsCOMPtr<nsIIdleService> idleService =
do_GetService("@mozilla.org/widget/idleservice;1", &rv);
do_GetService("@mozilla.org/widget/idleservice;1", &rv);
NS_ENSURE_SUCCESS(rv, false);
nsRefPtr<ParentIdleListener> listener = new ParentIdleListener(this, aObserver);
mIdleListeners.Put(aObserver, listener);
idleService->AddIdleObserver(listener, aIdleTimeInS);
nsRefPtr<ParentIdleListener> listener =
new ParentIdleListener(this, aObserver, aIdleTimeInS);
rv = idleService->AddIdleObserver(listener, aIdleTimeInS);
NS_ENSURE_SUCCESS(rv, false);
mIdleListeners.AppendElement(listener);
return true;
}
bool
ContentParent::RecvRemoveIdleObserver(const uint64_t& aObserver, const uint32_t& aIdleTimeInS)
{
nsresult rv;
nsCOMPtr<nsIIdleService> idleService =
do_GetService("@mozilla.org/widget/idleservice;1", &rv);
NS_ENSURE_SUCCESS(rv, false);
nsRefPtr<ParentIdleListener> listener;
bool found = mIdleListeners.Get(aObserver, &listener);
if (found) {
mIdleListeners.Remove(aObserver);
idleService->RemoveIdleObserver(listener, aIdleTimeInS);
for (int32_t i = mIdleListeners.Length() - 1; i >= 0; --i) {
listener = static_cast<ParentIdleListener*>(mIdleListeners[i].get());
if (listener->mObserver == aObserver &&
listener->mTime == aIdleTimeInS) {
nsresult rv;
nsCOMPtr<nsIIdleService> idleService =
do_GetService("@mozilla.org/widget/idleservice;1", &rv);
NS_ENSURE_SUCCESS(rv, false);
idleService->RemoveIdleObserver(listener, aIdleTimeInS);
mIdleListeners.RemoveElementAt(i);
break;
}
}
return true;
}

View File

@ -922,7 +922,7 @@ private:
nsRefPtr<nsConsoleService> mConsoleService;
nsConsoleService* GetConsoleService();
nsDataHashtable<nsUint64HashKey, nsRefPtr<ParentIdleListener> > mIdleListeners;
nsTArray<nsCOMPtr<nsIObserver>> mIdleListeners;
#ifdef MOZ_X11
// Dup of child's X socket, used to scope its resources to this
@ -942,17 +942,20 @@ private:
} // namespace mozilla
class ParentIdleListener : public nsIObserver {
friend class mozilla::dom::ContentParent;
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
ParentIdleListener(mozilla::dom::ContentParent* aParent, uint64_t aObserver)
: mParent(aParent), mObserver(aObserver)
ParentIdleListener(mozilla::dom::ContentParent* aParent, uint64_t aObserver, uint32_t aTime)
: mParent(aParent), mObserver(aObserver), mTime(aTime)
{}
private:
virtual ~ParentIdleListener() {}
nsRefPtr<mozilla::dom::ContentParent> mParent;
uint64_t mObserver;
uint32_t mTime;
};
#endif