Chromium Code Reviews| Index: Source/core/frame/PlatformEventDispatcher.cpp |
| diff --git a/Source/core/frame/PlatformEventDispatcher.cpp b/Source/core/frame/PlatformEventDispatcher.cpp |
| index b588df26190466b88d871cbc12c42ad46145b881..69156367d3f4dd9d8640a38c078d7fa543141fd2 100644 |
| --- a/Source/core/frame/PlatformEventDispatcher.cpp |
| +++ b/Source/core/frame/PlatformEventDispatcher.cpp |
| @@ -11,95 +11,52 @@ |
| namespace blink { |
| PlatformEventDispatcher::PlatformEventDispatcher() |
| - : m_needsPurge(false) |
| - , m_isDispatching(false) |
| { |
| } |
| void PlatformEventDispatcher::addController(PlatformEventController* controller) |
| { |
| + ASSERT(controller); |
| + |
| bool wasEmpty = m_controllers.isEmpty(); |
| - if (!m_controllers.contains(controller)) |
| - m_controllers.append(controller); |
| + m_controllers.add(controller); |
| if (wasEmpty) |
| startListening(); |
| } |
| void PlatformEventDispatcher::removeController(PlatformEventController* controller) |
| { |
| - // Do not actually remove the controller from the vector, instead zero them out. |
| - // The zeros are removed in these two cases: |
| - // 1. either immediately if we are not dispatching any events, |
| - // 2. or after events to all controllers have dispatched (see notifyControllers()). |
| - // This is to correctly handle the re-entrancy case when a controller is destroyed |
| - // while the events are still being dispatched. |
|
haraken
2015/08/19 11:12:51
This comment explains why we have to use a Vector
peria
2015/08/20 09:35:50
Ah, I understand that the main focus of this comme
timvolodine
2015/08/20 11:16:17
yes, the main concern here was that we can execute
|
| - size_t index = m_controllers.find(controller); |
| - if (index == kNotFound) |
| + if (!m_controllers.contains(controller)) |
| return; |
| - m_controllers[index] = nullptr; |
| - m_needsPurge = true; |
| - |
| - if (!m_isDispatching) |
| - purgeControllers(); |
| + m_controllers.remove(controller); |
| + purgeControllers(); |
| } |
| void PlatformEventDispatcher::purgeControllers() |
| { |
| - ASSERT(m_needsPurge); |
| - |
| - size_t i = 0; |
| - while (i < m_controllers.size()) { |
| - if (!m_controllers[i]) { |
| - m_controllers[i] = m_controllers.last(); |
| - m_controllers.removeLast(); |
| - } else { |
| - ++i; |
| - } |
| - } |
| - |
| - m_needsPurge = false; |
| - |
| if (m_controllers.isEmpty()) |
| stopListening(); |
| } |
| void PlatformEventDispatcher::notifyControllers() |
| { |
| - { |
| - TemporaryChange<bool> changeIsDispatching(m_isDispatching, true); |
| - // Don't notify controllers removed or added during event dispatch. |
| - size_t size = m_controllers.size(); |
| - for (size_t i = 0; i < size; ++i) { |
| - if (m_controllers[i]) |
| - m_controllers[i]->didUpdateData(); |
| - } |
| - } |
| - |
| - if (m_needsPurge) |
| - purgeControllers(); |
| + // didUpdateData() may delete the object itself, and it can lead to restructure m_controllers. |
| + // Thus we restore elements of m_controllers into a Vector to access all elements. |
| + HeapVector<PlatformEventController*> snapshotVector; |
| + for (PlatformEventController* controller : m_controllers) |
| + snapshotVector.append(controller); |
| + for (PlatformEventController* controller : snapshotVector) |
| + controller->didUpdateData(); |
| + |
| + purgeControllers(); |
| } |
| DEFINE_TRACE(PlatformEventDispatcher) |
| { |
| #if ENABLE(OILPAN) |
| - // Trace the backing store, the weak(&bare) element references won't be. |
| visitor->trace(m_controllers); |
| - visitor->template registerWeakMembers<PlatformEventDispatcher, &PlatformEventDispatcher::clearWeakMembers>(this); |
| #endif |
| } |
| -#if ENABLE(OILPAN) |
| -void PlatformEventDispatcher::clearWeakMembers(Visitor* visitor) |
| -{ |
| - for (size_t i = 0; i < m_controllers.size(); ++i) { |
| - if (!Heap::isHeapObjectAlive(m_controllers[i])) { |
| - m_controllers[i] = nullptr; |
| - m_needsPurge = true; |
| - } |
| - } |
| - // Next notification will purge the empty slots. |
| -} |
| -#endif |
| - |
| } // namespace blink |