Bug 401137. Silence ASSERTION: RefreshURIList timer callbacks should only be RefreshTimer objects. Docshell expects to be able to getCallback during a Timer fire. r=bzbarsky, sr=brendan, a=mconnor
Bug 401137. Silence ASSERTION: RefreshURIList timer callbacks should only be RefreshTimer objects. Docshell expects to be able to getCallback during a Timer fire. r=bzbarsky, sr=brendan, a=mconnor
--- a/xpcom/threads/nsTimerImpl.cpp
+++ b/xpcom/threads/nsTimerImpl.cpp
@@ -333,16 +333,18 @@ NS_IMETHODIMP nsTimerImpl::GetClosure(vo
return NS_OK;
}
NS_IMETHODIMP nsTimerImpl::GetCallback(nsITimerCallback **aCallback)
{
if (mCallbackType == CALLBACK_TYPE_INTERFACE)
NS_IF_ADDREF(*aCallback = mCallback.i);
+ else if (mTimerCallbackWhileFiring)
+ NS_ADDREF(*aCallback = mTimerCallbackWhileFiring);
else
*aCallback = nsnull;
return NS_OK;
}
void nsTimerImpl::Fire()
@@ -374,16 +376,18 @@ void nsTimerImpl::Fire()
if (mType == TYPE_REPEATING_PRECISE) {
// Precise repeating timers advance mTimeout by mDelay without fail before
// calling Fire().
timeout -= PR_MillisecondsToInterval(mDelay);
}
if (gThread)
gThread->UpdateFilter(mDelay, timeout, now);
+ if (mCallbackType == CALLBACK_TYPE_INTERFACE)
+ mTimerCallbackWhileFiring = mCallback.i;
mFiring = PR_TRUE;
// Handle callbacks that re-init the timer, but avoid leaking.
// See bug 330128.
CallbackUnion callback = mCallback;
PRUintn callbackType = mCallbackType;
if (callbackType == CALLBACK_TYPE_INTERFACE)
NS_ADDREF(callback.i);
@@ -415,16 +419,17 @@ void nsTimerImpl::Fire()
// The timer was a one-shot, or the callback was reinitialized.
if (callbackType == CALLBACK_TYPE_INTERFACE)
NS_RELEASE(callback.i);
else if (callbackType == CALLBACK_TYPE_OBSERVER)
NS_RELEASE(callback.o);
}
mFiring = PR_FALSE;
+ mTimerCallbackWhileFiring = nsnull;
#ifdef DEBUG_TIMERS
if (PR_LOG_TEST(gTimerLog, PR_LOG_DEBUG)) {
PR_LOG(gTimerLog, PR_LOG_DEBUG,
("[this=%p] Took %dms to fire timer callback\n",
this, PR_IntervalToMilliseconds(PR_IntervalNow() - now)));
}
#endif
--- a/xpcom/threads/nsTimerImpl.h
+++ b/xpcom/threads/nsTimerImpl.h
@@ -122,16 +122,20 @@ private:
void * mClosure;
union CallbackUnion {
nsTimerCallbackFunc c;
nsITimerCallback * i;
nsIObserver * o;
} mCallback;
+ // Some callers expect to be able to access the callback while the
+ // timer is firing.
+ nsCOMPtr<nsITimerCallback> mTimerCallbackWhileFiring;
+
// These members are set by Init (called from NS_NewTimer) and never reset.
PRUint8 mCallbackType;
// These members are set by the initiating thread, when the timer's type is
// changed and during the period where it fires on that thread.
PRUint8 mType;
PRPackedBool mFiring;