From 66d8174bb0bd20583a52e090db665c9392ade7da Mon Sep 17 00:00:00 2001 From: ben turner Date: Mon, 22 Jun 2009 15:08:04 +0200 Subject: [PATCH] Bug 498010 - Threads should release their observers when they are shut down; r=benjamin --- xpcom/threads/nsIThreadInternal.idl | 4 +++- xpcom/threads/nsThread.cpp | 11 +++++++++++ xpcom/threads/nsThreadManager.cpp | 5 +++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/xpcom/threads/nsIThreadInternal.idl b/xpcom/threads/nsIThreadInternal.idl index 94b2c82a5e1..d8f430c60d4 100644 --- a/xpcom/threads/nsIThreadInternal.idl +++ b/xpcom/threads/nsIThreadInternal.idl @@ -51,7 +51,9 @@ interface nsIThreadInternal : nsIThread /** * Get/set the current thread observer (may be null). This attribute may be * read from any thread, but must only be set on the thread corresponding to - * this thread object. + * this thread object. The observer will be released on the thread + * corresponding to this thread object after all other events have been + * processed during a call to Shutdown. */ attribute nsIThreadObserver observer; diff --git a/xpcom/threads/nsThread.cpp b/xpcom/threads/nsThread.cpp index 5988c88c3ae..f016a6559b5 100644 --- a/xpcom/threads/nsThread.cpp +++ b/xpcom/threads/nsThread.cpp @@ -280,6 +280,9 @@ nsThread::ThreadFunc(void *arg) event = new nsThreadShutdownAckEvent(self->mShutdownContext); self->mShutdownContext->joiningThread->Dispatch(event, NS_DISPATCH_NORMAL); + // Release any observer of the thread here. + self->SetObserver(nsnull); + NS_RELEASE(self); } @@ -468,6 +471,14 @@ nsThread::Shutdown() PR_JoinThread(mThread); mThread = nsnull; + +#ifdef DEBUG + { + nsAutoLock lock(mLock); + NS_ASSERTION(!mObserver, "Should have been cleared at shutdown!"); + } +#endif + return NS_OK; } diff --git a/xpcom/threads/nsThreadManager.cpp b/xpcom/threads/nsThreadManager.cpp index 19ddd19c6ea..2d363db0202 100644 --- a/xpcom/threads/nsThreadManager.cpp +++ b/xpcom/threads/nsThreadManager.cpp @@ -155,6 +155,11 @@ nsThreadManager::Shutdown() mThreadsByPRThread.Clear(); } + // Normally thread shutdown clears the observer for the thread, but since the + // main thread is special we do it manually here after we're sure all events + // have been processed. + mMainThread->SetObserver(nsnull); + // Release main thread object. mMainThread = nsnull;