From 412d4382795185f37913cc038650a13fc44d70fa Mon Sep 17 00:00:00 2001 From: "mccabe%netscape.com" Date: Mon, 9 Oct 2000 23:45:59 +0000 Subject: [PATCH] Fix to 53929. Fix previously-broken UnregisterListener method on console service, by proxy-wrapping the service we've been asked to remove before comparing it to those in the listener list. The saved listeners are already proxy-wrapped, so the previous straight compare failed. The equality check works because the proxy service caches proxies, and will always return the same wrapper. This fixes a leak and a situation that led to some asserts in XPConnect on shutdown. (Some listeners were proxy-wrapped JS objects.) r=jband. git-svn-id: svn://10.0.0.236/trunk@80765 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/xpcom/base/nsConsoleService.cpp | 65 ++++++++++++++++--------- mozilla/xpcom/base/nsConsoleService.h | 4 ++ 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/mozilla/xpcom/base/nsConsoleService.cpp b/mozilla/xpcom/base/nsConsoleService.cpp index 517f7462df3..1a17f7e51ff 100644 --- a/mozilla/xpcom/base/nsConsoleService.cpp +++ b/mozilla/xpcom/base/nsConsoleService.cpp @@ -240,24 +240,9 @@ nsConsoleService::RegisterListener(nsIConsoleListener *listener) { * thread-specific ways, and we always want to call them on their * originating thread. JavaScript is the motivating example. */ - nsCOMPtr proxyManager = - (do_GetService(NS_XPCOMPROXY_CONTRACTID)); - - if (proxyManager == nsnull) - return NS_ERROR_NOT_AVAILABLE; - nsCOMPtr proxiedListener; - /* - * NOTE this will fail if the calling thread doesn't have an eventQ. - * - * Would it be better to catch that case and leave the listener unproxied? - */ - rv = proxyManager->GetProxyForObject(NS_CURRENT_EVENTQ, - NS_GET_IID(nsIConsoleListener), - listener, - PROXY_ASYNC | PROXY_ALWAYS, - getter_AddRefs(proxiedListener)); + rv = GetProxyForListener(listener, getter_AddRefs(proxiedListener)); if (NS_FAILED(rv)) return rv; @@ -274,13 +259,49 @@ nsConsoleService::RegisterListener(nsIConsoleListener *listener) { NS_IMETHODIMP nsConsoleService::UnregisterListener(nsIConsoleListener *listener) { - nsAutoLock lock(mLock); + nsresult rv; - // ignore rv for now, as a comment says it returns prbool instead of - // nsresult. + nsCOMPtr proxiedListener; + rv = GetProxyForListener(listener, getter_AddRefs(proxiedListener)); + if (NS_FAILED(rv)) + return rv; - // Solaris needs the nsISupports cast to avoid confusion with - // another nsSupportsArray::RemoveElement overloading. - mListeners->RemoveElement((const nsISupports *)listener); + { + nsAutoLock lock(mLock); + + // ignore rv below for now, as a comment says it returns + // prbool instead of nsresult. + + // Solaris needs the nsISupports cast to avoid confusion with + // another nsSupportsArray::RemoveElement overloading. + mListeners->RemoveElement((const nsISupports *)proxiedListener); + + } return NS_OK; } + +nsresult +nsConsoleService::GetProxyForListener(nsIConsoleListener* aListener, + nsIConsoleListener** aProxy) +{ + nsresult rv; + *aProxy = nsnull; + + nsCOMPtr proxyManager = + (do_GetService(NS_XPCOMPROXY_CONTRACTID)); + + if (proxyManager == nsnull) + return NS_ERROR_NOT_AVAILABLE; + + /* + * NOTE this will fail if the calling thread doesn't have an eventQ. + * + * Would it be better to catch that case and leave the listener unproxied? + */ + rv = proxyManager->GetProxyForObject(NS_CURRENT_EVENTQ, + NS_GET_IID(nsIConsoleListener), + aListener, + PROXY_ASYNC | PROXY_ALWAYS, + (void**) aProxy); + return rv; +} diff --git a/mozilla/xpcom/base/nsConsoleService.h b/mozilla/xpcom/base/nsConsoleService.h index f09ca57da77..7c539f45b94 100644 --- a/mozilla/xpcom/base/nsConsoleService.h +++ b/mozilla/xpcom/base/nsConsoleService.h @@ -43,6 +43,10 @@ public: NS_DECL_NSICONSOLESERVICE private: + // build (or find) a proxy for the listener + nsresult GetProxyForListener(nsIConsoleListener* aListener, + nsIConsoleListener** aProxy); + // Circular buffer of saved messages nsIConsoleMessage **mMessages;