Changeset 114374 in webkit for trunk/Source/WebCore/xml/XMLHttpRequestProgressEventThrottle.cpp
- Timestamp:
- Apr 17, 2012, 7:02:07 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/xml/XMLHttpRequestProgressEventThrottle.cpp
r111717 r114374 1 1 /* 2 * Copyright (C) 2010 Julien Chaffraix <[email protected]> 3 * All right reserved.2 * Copyright (C) 2010 Julien Chaffraix <[email protected]> All right reserved. 3 * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies) 4 4 * 5 5 * Redistribution and use in source and binary forms, with or without … … 39 39 , m_loaded(0) 40 40 , m_total(0) 41 , m_suspended(false) 41 , m_deferEvents(false) 42 , m_dispatchDeferredEventsTimer(this, &XMLHttpRequestProgressEventThrottle::dispatchDeferredEvents) 42 43 { 43 44 ASSERT(target); … … 50 51 void XMLHttpRequestProgressEventThrottle::dispatchProgressEvent(bool lengthComputable, unsigned long long loaded, unsigned long long total) 51 52 { 52 ASSERT(!suspended()); 53 if (m_deferEvents) { 54 // Only store the latest progress event while suspended. 55 m_deferredProgressEvent = XMLHttpRequestProgressEvent::create(eventNames().progressEvent, lengthComputable, loaded, total); 56 return; 57 } 58 53 59 if (!isActive()) { 54 60 // The timer is not active so the least frequent event for now is every byte. … … 80 86 void XMLHttpRequestProgressEventThrottle::dispatchEvent(PassRefPtr<Event> event) 81 87 { 82 ASSERT(!suspended()); 83 // We should not have any pending events from a previous resume. 84 ASSERT(!m_pausedEvent); 85 86 m_target->dispatchEvent(event); 88 ASSERT(event); 89 if (m_deferEvents) { 90 if (m_deferredEvents.size() > 1 && event->type() == eventNames().readystatechangeEvent && event->type() == m_deferredEvents.last()->type()) { 91 // Readystatechange events are state-less so avoid repeating two identical events in a row on resume. 92 return; 93 } 94 m_deferredEvents.append(event); 95 } else 96 m_target->dispatchEvent(event); 87 97 } 88 98 … … 97 107 void XMLHttpRequestProgressEventThrottle::flushProgressEvent() 98 108 { 109 if (m_deferEvents && m_deferredProgressEvent) { 110 // Move the progress event to the queue, to get it in the right order on resume. 111 m_deferredEvents.append(m_deferredProgressEvent); 112 m_deferredProgressEvent = 0; 113 return; 114 } 115 99 116 if (!hasEventToDispatch()) 100 117 return; … … 110 127 } 111 128 112 void XMLHttpRequestProgressEventThrottle::dispatchPausedEvent() 113 { 114 ASSERT(!suspended()); 115 if (!m_pausedEvent) 116 return; 117 118 dispatchEvent(m_pausedEvent); 119 m_pausedEvent = 0; 129 void XMLHttpRequestProgressEventThrottle::dispatchDeferredEvents(Timer<XMLHttpRequestProgressEventThrottle>* timer) 130 { 131 ASSERT_UNUSED(timer, timer == &m_dispatchDeferredEventsTimer); 132 ASSERT(m_deferEvents); 133 m_deferEvents = false; 134 135 // Take over the deferred events before dispatching them which can potentially add more. 136 Vector<RefPtr<Event> > deferredEvents; 137 m_deferredEvents.swap(deferredEvents); 138 139 RefPtr<Event> deferredProgressEvent = m_deferredProgressEvent; 140 m_deferredProgressEvent = 0; 141 142 Vector<RefPtr<Event> >::const_iterator it = deferredEvents.begin(); 143 const Vector<RefPtr<Event> >::const_iterator end = deferredEvents.end(); 144 for (; it != end; ++it) 145 dispatchEvent(*it); 146 147 // The progress event will be in the m_deferredEvents vector if the load was finished while suspended. 148 // If not, just send the most up-to-date progress on resume. 149 if (deferredProgressEvent) 150 dispatchEvent(deferredProgressEvent); 120 151 } 121 152 … … 123 154 { 124 155 ASSERT(isActive()); 125 ASSERT(!suspended());126 ASSERT(!m_pausedEvent);127 156 if (!hasEventToDispatch()) { 128 157 // No progress event was queued since the previous dispatch, we can safely stop the timer. … … 143 172 void XMLHttpRequestProgressEventThrottle::suspend() 144 173 { 145 ASSERT(!m_pausedEvent); 146 147 m_suspended = true; 174 // If re-suspended before deferred events have been dispatched, just stop the dispatch 175 // and continue the last suspend. 176 if (m_dispatchDeferredEventsTimer.isActive()) { 177 ASSERT(m_deferEvents); 178 m_dispatchDeferredEventsTimer.stop(); 179 return; 180 } 181 ASSERT(!m_deferredProgressEvent); 182 ASSERT(m_deferredEvents.isEmpty()); 183 ASSERT(!m_deferEvents); 184 185 m_deferEvents = true; 148 186 // If we have a progress event waiting to be dispatched, 149 // just queueit.187 // just defer it. 150 188 if (hasEventToDispatch()) { 151 m_ pausedEvent = XMLHttpRequestProgressEvent::create(eventNames().progressEvent, m_lengthComputable, m_loaded, m_total);189 m_deferredProgressEvent = XMLHttpRequestProgressEvent::create(eventNames().progressEvent, m_lengthComputable, m_loaded, m_total); 152 190 m_total = 0; 153 191 m_loaded = 0; … … 161 199 ASSERT(!m_total); 162 200 163 m_suspended = false; 164 dispatchPausedEvent(); 201 // Do not dispatch events inline here, since ScriptExecutionContext is iterating over 202 // the list of active DOM objects to resume them, and any activated JS event-handler 203 // could insert new active DOM objects to the list. 204 // m_deferEvents is kept true until all deferred events have been dispatched. 205 m_dispatchDeferredEventsTimer.startOneShot(0); 165 206 } 166 207
Note:
See TracChangeset
for help on using the changeset viewer.