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
Родитель aa34b7b2b5
Коммит 7742c1eb59
2 изменённых файлов: 29 добавлений и 40 удалений

Просмотреть файл

@ -729,9 +729,6 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
// Initialize the PRCList (this).
PR_INIT_CLIST(this);
// Initialize timeout storage
PR_INIT_CLIST(&mTimeouts);
if (aOuterWindow) {
// |this| is an inner window, add this inner window to the outer
// window list of inners.
@ -1321,7 +1318,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow)
nsEventListenerManager)
for (nsTimeout* timeout = tmp->FirstTimeout();
tmp->IsTimeout(timeout);
timeout;
timeout = timeout->Next()) {
cb.NoteNativeChild(timeout, NS_CYCLE_COLLECTION_PARTICIPANT(nsTimeout));
}
@ -1427,9 +1424,7 @@ nsGlobalWindow::IsBlackForCC()
void
nsGlobalWindow::UnmarkGrayTimers()
{
for (nsTimeout* timeout = FirstTimeout();
timeout && IsTimeout(timeout);
timeout = timeout->Next()) {
for (nsTimeout* timeout = FirstTimeout(); timeout; timeout = timeout->Next()) {
if (timeout->mScriptHandler) {
JSObject* o = timeout->mScriptHandler->GetScriptObject();
xpc_UnmarkGrayObject(o);
@ -2319,8 +2314,7 @@ nsGlobalWindow::DetachFromDocShell()
// (mJSObject) so that it can be retrieved later (until it is
// finalized by the JS GC).
NS_ASSERTION(PR_CLIST_IS_EMPTY(&mTimeouts),
"Uh, outer window holds timeouts!");
NS_ASSERTION(mTimeouts.isEmpty(), "Uh, outer window holds timeouts!");
// Call FreeInnerObjects on all inner windows, not just the current
// 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
// as the deadline.
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)) &&
(timeout->mFiringDepth == 0)) {
// 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.
dummy_timeout.mFiringDepth = firingDepth;
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
// dummy timeout.
@ -10022,7 +10016,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
// we need to reset the pointer to the following timeout.
nextTimeout = timeout->Next();
PR_REMOVE_LINK(timeout);
timeout->remove();
if (needsReinsertion) {
// 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
PR_REMOVE_LINK(&dummy_timeout);
dummy_timeout.remove();
mTimeoutInsertionPoint = last_insertion_point;
}
@ -10073,9 +10067,7 @@ nsGlobalWindow::ClearTimeoutOrInterval(int32_t aTimerID)
uint32_t public_id = (uint32_t)aTimerID;
nsTimeout *timeout;
for (timeout = FirstTimeout();
IsTimeout(timeout);
timeout = timeout->Next()) {
for (timeout = FirstTimeout(); timeout; timeout = timeout->Next()) {
if (timeout->mPublicId == public_id) {
if (timeout->mRunning) {
/* We're running from inside the timeout. Mark this
@ -10085,7 +10077,7 @@ nsGlobalWindow::ClearTimeoutOrInterval(int32_t aTimerID)
}
else {
/* Delete the timeout from the pending timeout list */
PR_REMOVE_LINK(timeout);
timeout->remove();
if (timeout->mTimer) {
timeout->mTimer->Cancel();
@ -10121,7 +10113,7 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow()
// Otherwise, start at the beginning of the list.
for (nsTimeout *timeout = mTimeoutInsertionPoint ?
mTimeoutInsertionPoint->Next() : FirstTimeout();
IsTimeout(timeout); ) {
timeout; ) {
// It's important that this check be <= so that we guarantee that
// taking NS_MAX with |now| won't make a quantity equal to
// timeout->mWhen below.
@ -10168,9 +10160,9 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow()
// 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
// |timeout| before nextTimeout.
NS_ASSERTION(!IsTimeout(nextTimeout) ||
NS_ASSERTION(!nextTimeout ||
timeout->mWhen < nextTimeout->mWhen, "How did that happen?");
PR_REMOVE_LINK(timeout);
timeout->remove();
// InsertTimeoutIntoList will addref |timeout| and reset
// mFiringDepth. Make sure to undo that after calling it.
uint32_t firingDepth = timeout->mFiringDepth;
@ -10199,7 +10191,7 @@ nsGlobalWindow::ClearAllTimeouts()
{
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
window, e.g. as a result of document.write from a timeout,
then we need to reset the list insertion point for
@ -10228,7 +10220,7 @@ nsGlobalWindow::ClearAllTimeouts()
}
// Clear out our list
PR_INIT_CLIST(&mTimeouts);
mTimeouts.clear();
}
void
@ -10242,7 +10234,7 @@ nsGlobalWindow::InsertTimeoutIntoList(nsTimeout *aTimeout)
// insertion at the end.
nsTimeout* prevSibling;
for (prevSibling = LastTimeout();
IsTimeout(prevSibling) && prevSibling != mTimeoutInsertionPoint &&
prevSibling && prevSibling != mTimeoutInsertionPoint &&
// This condition needs to match the one in SetTimeoutOrInterval that
// determines whether to set mWhen or mTimeRemaining.
((IsFrozen() || mTimeoutsSuspendDepth) ?
@ -10253,7 +10245,11 @@ nsGlobalWindow::InsertTimeoutIntoList(nsTimeout *aTimeout)
}
// Now link in aTimeout after prevSibling.
PR_INSERT_AFTER(aTimeout, prevSibling);
if (prevSibling) {
prevSibling->setNext(aTimeout);
} else {
mTimeouts.insertFront(aTimeout);
}
aTimeout->mFiringDepth = 0;
@ -10545,7 +10541,7 @@ nsGlobalWindow::SuspendTimeouts(uint32_t aIncrease,
mozilla::dom::workers::SuspendWorkersForWindow(cx, this);
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.
if (t->mWhen > now)
t->mTimeRemaining = t->mWhen - now;
@ -10633,7 +10629,7 @@ nsGlobalWindow::ResumeTimeouts(bool aThawChildren)
bool _seenDummyTimeout = false;
#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
// case we have a dummy timeout in the list that *must not* be resumed. It
// can be identified by a null mWindow.

Просмотреть файл

@ -59,6 +59,7 @@
#include "nsIContent.h"
#include "nsIIDBFactory.h"
#include "nsFrameMessageManager.h"
#include "mozilla/LinkedList.h"
#include "mozilla/TimeStamp.h"
#include "nsIDOMTouchEvent.h"
#include "nsIInlineEventHandlers.h"
@ -134,7 +135,7 @@ NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow,
* timeout. Holds a strong reference to an nsIScriptTimeoutHandler, which
* abstracts the language specific cruft.
*/
struct nsTimeout : PRCList
struct nsTimeout : mozilla::LinkedListElement<nsTimeout>
{
nsTimeout();
~nsTimeout();
@ -145,13 +146,11 @@ struct nsTimeout : PRCList
nsrefcnt AddRef();
nsTimeout* Next() {
// Note: might not actually return an nsTimeout. Use IsTimeout to check.
return static_cast<nsTimeout*>(PR_NEXT_LINK(this));
return getNext();
}
nsTimeout* Prev() {
// Note: might not actually return an nsTimeout. Use IsTimeout to check.
return static_cast<nsTimeout*>(PR_PREV_LINK(this));
return getPrevious();
}
nsresult InitTimer(nsTimerCallbackFunc aFunc, uint64_t delay) {
@ -873,17 +872,11 @@ protected:
bool IsInModalState();
nsTimeout* FirstTimeout() {
// Note: might not actually return an nsTimeout. Use IsTimeout to check.
return static_cast<nsTimeout*>(PR_LIST_HEAD(&mTimeouts));
return mTimeouts.getFirst();
}
nsTimeout* LastTimeout() {
// Note: might not actually return an nsTimeout. Use IsTimeout to check.
return static_cast<nsTimeout*>(PR_LIST_TAIL(&mTimeouts));
}
bool IsTimeout(PRCList* aList) {
return aList != &mTimeouts;
return mTimeouts.getLast();
}
// 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
// mTimeoutInsertionPoint may have a later mWhen than some of the timeouts
// that come after it.
PRCList mTimeouts;
mozilla::LinkedList<nsTimeout> mTimeouts;
// 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
// ResetTimersForNonBackgroundWindow needs to change.