diff options
Diffstat (limited to 'Source/WebCore/dom/GenericEventQueue.cpp')
-rw-r--r-- | Source/WebCore/dom/GenericEventQueue.cpp | 112 |
1 files changed, 74 insertions, 38 deletions
diff --git a/Source/WebCore/dom/GenericEventQueue.cpp b/Source/WebCore/dom/GenericEventQueue.cpp index a04e489c7..cd201a369 100644 --- a/Source/WebCore/dom/GenericEventQueue.cpp +++ b/Source/WebCore/dom/GenericEventQueue.cpp @@ -10,10 +10,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -24,21 +24,19 @@ */ #include "config.h" - #include "GenericEventQueue.h" #include "Event.h" +#include "EventTarget.h" +#include "Timer.h" +#include <wtf/MainThread.h> +#include <wtf/NeverDestroyed.h> namespace WebCore { -PassOwnPtr<GenericEventQueue> GenericEventQueue::create(EventTarget* owner) -{ - return adoptPtr(new GenericEventQueue(owner)); -} - -GenericEventQueue::GenericEventQueue(EventTarget* owner) +GenericEventQueue::GenericEventQueue(EventTarget& owner) : m_owner(owner) - , m_timer(this, &GenericEventQueue::timerFired) + , m_weakPtrFactory(this) , m_isClosed(false) { } @@ -47,67 +45,105 @@ GenericEventQueue::~GenericEventQueue() { } -bool GenericEventQueue::enqueueEvent(PassRefPtr<Event> event) +void GenericEventQueue::enqueueEvent(RefPtr<Event>&& event) { if (m_isClosed) - return false; + return; - if (event->target() == m_owner) - event->setTarget(0); + if (event->target() == &m_owner) + event->setTarget(nullptr); - m_pendingEvents.append(event); + m_pendingEvents.append(WTFMove(event)); - if (!m_timer.isActive()) - m_timer.startOneShot(0); + if (m_isSuspended) + return; - return true; + pendingQueues().append(m_weakPtrFactory.createWeakPtr()); + if (!sharedTimer().isActive()) + sharedTimer().startOneShot(0); } -bool GenericEventQueue::cancelEvent(Event* event) +Timer& GenericEventQueue::sharedTimer() { - bool found = m_pendingEvents.contains(event); + ASSERT(isMainThread()); + static NeverDestroyed<Timer> timer(GenericEventQueue::sharedTimerFired); + return timer.get(); +} - if (found) - m_pendingEvents.remove(m_pendingEvents.find(event)); +void GenericEventQueue::sharedTimerFired() +{ + ASSERT(!sharedTimer().isActive()); + ASSERT(!pendingQueues().isEmpty()); + + while (!pendingQueues().isEmpty()) { + WeakPtr<GenericEventQueue> queue = pendingQueues().takeFirst(); + if (!queue) + continue; + queue->dispatchOneEvent(); + } - if (m_pendingEvents.isEmpty()) - m_timer.stop(); + if (sharedTimer().isActive()) + sharedTimer().stop(); +} - return found; +Deque<WeakPtr<GenericEventQueue>>& GenericEventQueue::pendingQueues() +{ + ASSERT(isMainThread()); + static NeverDestroyed<Deque<WeakPtr<GenericEventQueue>>> queues; + return queues.get(); } -void GenericEventQueue::timerFired(Timer<GenericEventQueue>*) +void GenericEventQueue::dispatchOneEvent() { - ASSERT(!m_timer.isActive()); ASSERT(!m_pendingEvents.isEmpty()); - Vector<RefPtr<Event> > pendingEvents; - m_pendingEvents.swap(pendingEvents); - - RefPtr<EventTarget> protect(m_owner); - for (unsigned i = 0; i < pendingEvents.size(); ++i) { - EventTarget* target = pendingEvents[i]->target() ? pendingEvents[i]->target() : m_owner; - target->dispatchEvent(pendingEvents[i].release()); - } + Ref<EventTarget> protect(m_owner); + RefPtr<Event> event = m_pendingEvents.takeFirst(); + EventTarget& target = event->target() ? *event->target() : m_owner; + target.dispatchEvent(*event); } void GenericEventQueue::close() { m_isClosed = true; - m_timer.stop(); + m_weakPtrFactory.revokeAll(); m_pendingEvents.clear(); } void GenericEventQueue::cancelAllEvents() { - m_timer.stop(); + m_weakPtrFactory.revokeAll(); m_pendingEvents.clear(); } bool GenericEventQueue::hasPendingEvents() const { - return m_pendingEvents.size(); + return !m_pendingEvents.isEmpty(); +} + +void GenericEventQueue::suspend() +{ + ASSERT(!m_isSuspended); + m_isSuspended = true; + m_weakPtrFactory.revokeAll(); +} + +void GenericEventQueue::resume() +{ + if (!m_isSuspended) + return; + + m_isSuspended = false; + + if (m_pendingEvents.isEmpty()) + return; + + for (unsigned i = 0; i < m_pendingEvents.size(); ++i) + pendingQueues().append(m_weakPtrFactory.createWeakPtr()); + + if (!sharedTimer().isActive()) + sharedTimer().startOneShot(0); } } |