Bug 803665 - convert nsGlobalWindow's timeout list to use mozilla::LinkedList; r=bz

This commit is contained in:
Nathan Froyd 2012-11-01 10:06:22 -04:00
parent aa34b7b2b5
commit 7742c1eb59
2 changed files with 29 additions and 40 deletions

View File

@ -729,9 +729,6 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
// Initialize the PRCList (this). // Initialize the PRCList (this).
PR_INIT_CLIST(this); PR_INIT_CLIST(this);
// Initialize timeout storage
PR_INIT_CLIST(&mTimeouts);
if (aOuterWindow) { if (aOuterWindow) {
// |this| is an inner window, add this inner window to the outer // |this| is an inner window, add this inner window to the outer
// window list of inners. // window list of inners.
@ -1321,7 +1318,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow)
nsEventListenerManager) nsEventListenerManager)
for (nsTimeout* timeout = tmp->FirstTimeout(); for (nsTimeout* timeout = tmp->FirstTimeout();
tmp->IsTimeout(timeout); timeout;
timeout = timeout->Next()) { timeout = timeout->Next()) {
cb.NoteNativeChild(timeout, NS_CYCLE_COLLECTION_PARTICIPANT(nsTimeout)); cb.NoteNativeChild(timeout, NS_CYCLE_COLLECTION_PARTICIPANT(nsTimeout));
} }
@ -1427,9 +1424,7 @@ nsGlobalWindow::IsBlackForCC()
void void
nsGlobalWindow::UnmarkGrayTimers() nsGlobalWindow::UnmarkGrayTimers()
{ {
for (nsTimeout* timeout = FirstTimeout(); for (nsTimeout* timeout = FirstTimeout(); timeout; timeout = timeout->Next()) {
timeout && IsTimeout(timeout);
timeout = timeout->Next()) {
if (timeout->mScriptHandler) { if (timeout->mScriptHandler) {
JSObject* o = timeout->mScriptHandler->GetScriptObject(); JSObject* o = timeout->mScriptHandler->GetScriptObject();
xpc_UnmarkGrayObject(o); xpc_UnmarkGrayObject(o);
@ -2319,8 +2314,7 @@ nsGlobalWindow::DetachFromDocShell()
// (mJSObject) so that it can be retrieved later (until it is // (mJSObject) so that it can be retrieved later (until it is
// finalized by the JS GC). // finalized by the JS GC).
NS_ASSERTION(PR_CLIST_IS_EMPTY(&mTimeouts), NS_ASSERTION(mTimeouts.isEmpty(), "Uh, outer window holds timeouts!");
"Uh, outer window holds timeouts!");
// Call FreeInnerObjects on all inner windows, not just the current // Call FreeInnerObjects on all inner windows, not just the current
// one, since some could be held by WindowStateHolder objects that // one, since some could be held by WindowStateHolder objects that
@ -9905,7 +9899,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
// timeout events fire "early", so we need to test the timer as well // timeout events fire "early", so we need to test the timer as well
// as the deadline. // as the deadline.
last_expired_timeout = nullptr; last_expired_timeout = nullptr;
for (timeout = FirstTimeout(); IsTimeout(timeout); timeout = timeout->Next()) { for (timeout = FirstTimeout(); timeout; timeout = timeout->Next()) {
if (((timeout == aTimeout) || (timeout->mWhen <= deadline)) && if (((timeout == aTimeout) || (timeout->mWhen <= deadline)) &&
(timeout->mFiringDepth == 0)) { (timeout->mFiringDepth == 0)) {
// Mark any timeouts that are on the list to be fired with the // Mark any timeouts that are on the list to be fired with the
@ -9939,7 +9933,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
// list for any timeouts inserted as a result of running a timeout. // list for any timeouts inserted as a result of running a timeout.
dummy_timeout.mFiringDepth = firingDepth; dummy_timeout.mFiringDepth = firingDepth;
dummy_timeout.mWhen = now; dummy_timeout.mWhen = now;
PR_INSERT_AFTER(&dummy_timeout, last_expired_timeout); last_expired_timeout->setNext(&dummy_timeout);
// Don't let ClearWindowTimeouts throw away our stack-allocated // Don't let ClearWindowTimeouts throw away our stack-allocated
// dummy timeout. // dummy timeout.
@ -10022,7 +10016,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
// we need to reset the pointer to the following timeout. // we need to reset the pointer to the following timeout.
nextTimeout = timeout->Next(); nextTimeout = timeout->Next();
PR_REMOVE_LINK(timeout); timeout->remove();
if (needsReinsertion) { if (needsReinsertion) {
// Insert interval timeout onto list sorted in deadline order. // Insert interval timeout onto list sorted in deadline order.
@ -10035,7 +10029,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
} }
// Take the dummy timeout off the head of the list // Take the dummy timeout off the head of the list
PR_REMOVE_LINK(&dummy_timeout); dummy_timeout.remove();
mTimeoutInsertionPoint = last_insertion_point; mTimeoutInsertionPoint = last_insertion_point;
} }
@ -10073,9 +10067,7 @@ nsGlobalWindow::ClearTimeoutOrInterval(int32_t aTimerID)
uint32_t public_id = (uint32_t)aTimerID; uint32_t public_id = (uint32_t)aTimerID;
nsTimeout *timeout; nsTimeout *timeout;
for (timeout = FirstTimeout(); for (timeout = FirstTimeout(); timeout; timeout = timeout->Next()) {
IsTimeout(timeout);
timeout = timeout->Next()) {
if (timeout->mPublicId == public_id) { if (timeout->mPublicId == public_id) {
if (timeout->mRunning) { if (timeout->mRunning) {
/* We're running from inside the timeout. Mark this /* We're running from inside the timeout. Mark this
@ -10085,7 +10077,7 @@ nsGlobalWindow::ClearTimeoutOrInterval(int32_t aTimerID)
} }
else { else {
/* Delete the timeout from the pending timeout list */ /* Delete the timeout from the pending timeout list */
PR_REMOVE_LINK(timeout); timeout->remove();
if (timeout->mTimer) { if (timeout->mTimer) {
timeout->mTimer->Cancel(); timeout->mTimer->Cancel();
@ -10121,7 +10113,7 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow()
// Otherwise, start at the beginning of the list. // Otherwise, start at the beginning of the list.
for (nsTimeout *timeout = mTimeoutInsertionPoint ? for (nsTimeout *timeout = mTimeoutInsertionPoint ?
mTimeoutInsertionPoint->Next() : FirstTimeout(); mTimeoutInsertionPoint->Next() : FirstTimeout();
IsTimeout(timeout); ) { timeout; ) {
// It's important that this check be <= so that we guarantee that // It's important that this check be <= so that we guarantee that
// taking NS_MAX with |now| won't make a quantity equal to // taking NS_MAX with |now| won't make a quantity equal to
// timeout->mWhen below. // timeout->mWhen below.
@ -10168,9 +10160,9 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow()
// It is safe to remove and re-insert because mWhen is now // It is safe to remove and re-insert because mWhen is now
// strictly smaller than it used to be, so we know we'll insert // strictly smaller than it used to be, so we know we'll insert
// |timeout| before nextTimeout. // |timeout| before nextTimeout.
NS_ASSERTION(!IsTimeout(nextTimeout) || NS_ASSERTION(!nextTimeout ||
timeout->mWhen < nextTimeout->mWhen, "How did that happen?"); timeout->mWhen < nextTimeout->mWhen, "How did that happen?");
PR_REMOVE_LINK(timeout); timeout->remove();
// InsertTimeoutIntoList will addref |timeout| and reset // InsertTimeoutIntoList will addref |timeout| and reset
// mFiringDepth. Make sure to undo that after calling it. // mFiringDepth. Make sure to undo that after calling it.
uint32_t firingDepth = timeout->mFiringDepth; uint32_t firingDepth = timeout->mFiringDepth;
@ -10199,7 +10191,7 @@ nsGlobalWindow::ClearAllTimeouts()
{ {
nsTimeout *timeout, *nextTimeout; nsTimeout *timeout, *nextTimeout;
for (timeout = FirstTimeout(); IsTimeout(timeout); timeout = nextTimeout) { for (timeout = FirstTimeout(); timeout; timeout = nextTimeout) {
/* If RunTimeout() is higher up on the stack for this /* If RunTimeout() is higher up on the stack for this
window, e.g. as a result of document.write from a timeout, window, e.g. as a result of document.write from a timeout,
then we need to reset the list insertion point for then we need to reset the list insertion point for
@ -10228,7 +10220,7 @@ nsGlobalWindow::ClearAllTimeouts()
} }
// Clear out our list // Clear out our list
PR_INIT_CLIST(&mTimeouts); mTimeouts.clear();
} }
void void
@ -10242,7 +10234,7 @@ nsGlobalWindow::InsertTimeoutIntoList(nsTimeout *aTimeout)
// insertion at the end. // insertion at the end.
nsTimeout* prevSibling; nsTimeout* prevSibling;
for (prevSibling = LastTimeout(); for (prevSibling = LastTimeout();
IsTimeout(prevSibling) && prevSibling != mTimeoutInsertionPoint && prevSibling && prevSibling != mTimeoutInsertionPoint &&
// This condition needs to match the one in SetTimeoutOrInterval that // This condition needs to match the one in SetTimeoutOrInterval that
// determines whether to set mWhen or mTimeRemaining. // determines whether to set mWhen or mTimeRemaining.
((IsFrozen() || mTimeoutsSuspendDepth) ? ((IsFrozen() || mTimeoutsSuspendDepth) ?
@ -10253,7 +10245,11 @@ nsGlobalWindow::InsertTimeoutIntoList(nsTimeout *aTimeout)
} }
// Now link in aTimeout after prevSibling. // Now link in aTimeout after prevSibling.
PR_INSERT_AFTER(aTimeout, prevSibling); if (prevSibling) {
prevSibling->setNext(aTimeout);
} else {
mTimeouts.insertFront(aTimeout);
}
aTimeout->mFiringDepth = 0; aTimeout->mFiringDepth = 0;
@ -10545,7 +10541,7 @@ nsGlobalWindow::SuspendTimeouts(uint32_t aIncrease,
mozilla::dom::workers::SuspendWorkersForWindow(cx, this); mozilla::dom::workers::SuspendWorkersForWindow(cx, this);
TimeStamp now = TimeStamp::Now(); TimeStamp now = TimeStamp::Now();
for (nsTimeout *t = FirstTimeout(); IsTimeout(t); t = t->Next()) { for (nsTimeout *t = FirstTimeout(); t; t = t->Next()) {
// Set mTimeRemaining to be the time remaining for this timer. // Set mTimeRemaining to be the time remaining for this timer.
if (t->mWhen > now) if (t->mWhen > now)
t->mTimeRemaining = t->mWhen - now; t->mTimeRemaining = t->mWhen - now;
@ -10633,7 +10629,7 @@ nsGlobalWindow::ResumeTimeouts(bool aThawChildren)
bool _seenDummyTimeout = false; bool _seenDummyTimeout = false;
#endif #endif
for (nsTimeout *t = FirstTimeout(); IsTimeout(t); t = t->Next()) { for (nsTimeout *t = FirstTimeout(); t; t = t->Next()) {
// There's a chance we're being called with RunTimeout on the stack in which // There's a chance we're being called with RunTimeout on the stack in which
// case we have a dummy timeout in the list that *must not* be resumed. It // case we have a dummy timeout in the list that *must not* be resumed. It
// can be identified by a null mWindow. // can be identified by a null mWindow.

View File

@ -59,6 +59,7 @@
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIIDBFactory.h" #include "nsIIDBFactory.h"
#include "nsFrameMessageManager.h" #include "nsFrameMessageManager.h"
#include "mozilla/LinkedList.h"
#include "mozilla/TimeStamp.h" #include "mozilla/TimeStamp.h"
#include "nsIDOMTouchEvent.h" #include "nsIDOMTouchEvent.h"
#include "nsIInlineEventHandlers.h" #include "nsIInlineEventHandlers.h"
@ -134,7 +135,7 @@ NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow,
* timeout. Holds a strong reference to an nsIScriptTimeoutHandler, which * timeout. Holds a strong reference to an nsIScriptTimeoutHandler, which
* abstracts the language specific cruft. * abstracts the language specific cruft.
*/ */
struct nsTimeout : PRCList struct nsTimeout : mozilla::LinkedListElement<nsTimeout>
{ {
nsTimeout(); nsTimeout();
~nsTimeout(); ~nsTimeout();
@ -145,13 +146,11 @@ struct nsTimeout : PRCList
nsrefcnt AddRef(); nsrefcnt AddRef();
nsTimeout* Next() { nsTimeout* Next() {
// Note: might not actually return an nsTimeout. Use IsTimeout to check. return getNext();
return static_cast<nsTimeout*>(PR_NEXT_LINK(this));
} }
nsTimeout* Prev() { nsTimeout* Prev() {
// Note: might not actually return an nsTimeout. Use IsTimeout to check. return getPrevious();
return static_cast<nsTimeout*>(PR_PREV_LINK(this));
} }
nsresult InitTimer(nsTimerCallbackFunc aFunc, uint64_t delay) { nsresult InitTimer(nsTimerCallbackFunc aFunc, uint64_t delay) {
@ -873,17 +872,11 @@ protected:
bool IsInModalState(); bool IsInModalState();
nsTimeout* FirstTimeout() { nsTimeout* FirstTimeout() {
// Note: might not actually return an nsTimeout. Use IsTimeout to check. return mTimeouts.getFirst();
return static_cast<nsTimeout*>(PR_LIST_HEAD(&mTimeouts));
} }
nsTimeout* LastTimeout() { nsTimeout* LastTimeout() {
// Note: might not actually return an nsTimeout. Use IsTimeout to check. return mTimeouts.getLast();
return static_cast<nsTimeout*>(PR_LIST_TAIL(&mTimeouts));
}
bool IsTimeout(PRCList* aList) {
return aList != &mTimeouts;
} }
// Convenience functions for the many methods that need to scale // Convenience functions for the many methods that need to scale
@ -1053,7 +1046,7 @@ protected:
// non-null. In that case, the dummy timeout pointed to by // non-null. In that case, the dummy timeout pointed to by
// mTimeoutInsertionPoint may have a later mWhen than some of the timeouts // mTimeoutInsertionPoint may have a later mWhen than some of the timeouts
// that come after it. // that come after it.
PRCList mTimeouts; mozilla::LinkedList<nsTimeout> mTimeouts;
// If mTimeoutInsertionPoint is non-null, insertions should happen after it. // If mTimeoutInsertionPoint is non-null, insertions should happen after it.
// This is a dummy timeout at the moment; if that ever changes, the logic in // This is a dummy timeout at the moment; if that ever changes, the logic in
// ResetTimersForNonBackgroundWindow needs to change. // ResetTimersForNonBackgroundWindow needs to change.