Title: [86838] trunk/Source/WebCore
- Revision
- 86838
- Author
- [email protected]
- Date
- 2011-05-19 05:03:58 -0700 (Thu, 19 May 2011)
Log Message
2011-05-19 David Grogan <[email protected]>
Reviewed by David Levin.
Make EventQueue post a Task to the task queue for each asynchronous event
https://bugs.webkit.org/show_bug.cgi?id=60790
Currently EventQueue queues up events to be fired asynchronously and
fires each of them when a single DOMTimer goes off. In the words of
dimich, "Having 2 queues will sooner or later cause problems with
ordering of tasks, termination, suspension and other things that all
require some control on how queues operate."
No new tests; this is just a refactoring to avoid potential future
problems.
* dom/EventQueue.cpp:
(WebCore::EventQueue::EventQueue):
(WebCore::EventQueue::EventDispatcherTask::create):
(WebCore::EventQueue::EventDispatcherTask::dispatchEvent):
(WebCore::EventQueue::EventDispatcherTask::performTask):
(WebCore::EventQueue::EventDispatcherTask::cancel):
(WebCore::EventQueue::EventDispatcherTask::EventDispatcherTask):
(WebCore::EventQueue::removeEvent):
(WebCore::EventQueue::enqueueEvent):
(WebCore::EventQueue::enqueueOrDispatchScrollEvent):
(WebCore::EventQueue::cancelEvent):
(WebCore::EventQueue::cancelQueuedEvents):
* dom/EventQueue.h:
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (86837 => 86838)
--- trunk/Source/WebCore/ChangeLog 2011-05-19 11:47:02 UTC (rev 86837)
+++ trunk/Source/WebCore/ChangeLog 2011-05-19 12:03:58 UTC (rev 86838)
@@ -1,3 +1,33 @@
+2011-05-19 David Grogan <[email protected]>
+
+ Reviewed by David Levin.
+
+ Make EventQueue post a Task to the task queue for each asynchronous event
+ https://bugs.webkit.org/show_bug.cgi?id=60790
+
+ Currently EventQueue queues up events to be fired asynchronously and
+ fires each of them when a single DOMTimer goes off. In the words of
+ dimich, "Having 2 queues will sooner or later cause problems with
+ ordering of tasks, termination, suspension and other things that all
+ require some control on how queues operate."
+
+ No new tests; this is just a refactoring to avoid potential future
+ problems.
+
+ * dom/EventQueue.cpp:
+ (WebCore::EventQueue::EventQueue):
+ (WebCore::EventQueue::EventDispatcherTask::create):
+ (WebCore::EventQueue::EventDispatcherTask::dispatchEvent):
+ (WebCore::EventQueue::EventDispatcherTask::performTask):
+ (WebCore::EventQueue::EventDispatcherTask::cancel):
+ (WebCore::EventQueue::EventDispatcherTask::EventDispatcherTask):
+ (WebCore::EventQueue::removeEvent):
+ (WebCore::EventQueue::enqueueEvent):
+ (WebCore::EventQueue::enqueueOrDispatchScrollEvent):
+ (WebCore::EventQueue::cancelEvent):
+ (WebCore::EventQueue::cancelQueuedEvents):
+ * dom/EventQueue.h:
+
2011-05-18 Yury Semikhatsky <[email protected]>
Reviewed by Pavel Feldman.
Modified: trunk/Source/WebCore/dom/Document.h (86837 => 86838)
--- trunk/Source/WebCore/dom/Document.h 2011-05-19 11:47:02 UTC (rev 86837)
+++ trunk/Source/WebCore/dom/Document.h 2011-05-19 12:03:58 UTC (rev 86838)
@@ -1374,7 +1374,7 @@
bool m_usingGeolocation;
- RefPtr<EventQueue> m_eventQueue;
+ OwnPtr<EventQueue> m_eventQueue;
RefPtr<DocumentWeakReference> m_weakReference;
Modified: trunk/Source/WebCore/dom/EventQueue.cpp (86837 => 86838)
--- trunk/Source/WebCore/dom/EventQueue.cpp 2011-05-19 11:47:02 UTC (rev 86837)
+++ trunk/Source/WebCore/dom/EventQueue.cpp 2011-05-19 12:03:58 UTC (rev 86838)
@@ -33,7 +33,6 @@
#include "EventNames.h"
#include "RuntimeApplicationChecks.h"
#include "ScriptExecutionContext.h"
-#include "SuspendableTimer.h"
namespace WebCore {
@@ -43,42 +42,79 @@
return applicationIsSafari() && (document->url().protocolIs("feed") || document->url().protocolIs("feeds"));
}
-class EventQueueTimer : public SuspendableTimer {
- WTF_MAKE_NONCOPYABLE(EventQueueTimer);
-public:
- EventQueueTimer(EventQueue* eventQueue, ScriptExecutionContext* context)
- : SuspendableTimer(context)
- , m_eventQueue(eventQueue) { }
-
-private:
- virtual void fired() { m_eventQueue->pendingEventTimerFired(); }
- EventQueue* m_eventQueue;
-};
-
-PassRefPtr<EventQueue> EventQueue::create(ScriptExecutionContext* context)
+PassOwnPtr<EventQueue> EventQueue::create(ScriptExecutionContext* context)
{
- return adoptRef(new EventQueue(context));
+ return adoptPtr(new EventQueue(context));
}
EventQueue::EventQueue(ScriptExecutionContext* context)
- : m_pendingEventTimer(adoptPtr(new EventQueueTimer(this, context)))
+ : m_scriptExecutionContext(context)
{
}
EventQueue::~EventQueue()
{
+ cancelQueuedEvents();
}
-void EventQueue::enqueueEvent(PassRefPtr<Event> event)
+class EventQueue::EventDispatcherTask : public ScriptExecutionContext::Task {
+public:
+ static PassOwnPtr<EventDispatcherTask> create(PassRefPtr<Event> event, EventQueue* eventQueue)
+ {
+ return adoptPtr(new EventDispatcherTask(event, eventQueue));
+ }
+
+ void dispatchEvent(ScriptExecutionContext*, PassRefPtr<Event> event)
+ {
+ EventTarget* eventTarget = event->target();
+ if (eventTarget->toDOMWindow())
+ eventTarget->toDOMWindow()->dispatchEvent(event, 0);
+ else
+ eventTarget->dispatchEvent(event);
+ }
+
+ virtual void performTask(ScriptExecutionContext* context)
+ {
+ if (m_isCancelled)
+ return;
+ m_eventQueue->removeEvent(m_event.get());
+ dispatchEvent(context, m_event);
+ }
+
+ void cancel()
+ {
+ m_isCancelled = true;
+ m_event.clear();
+ }
+
+private:
+ EventDispatcherTask(PassRefPtr<Event> event, EventQueue* eventQueue)
+ : m_event(event)
+ , m_eventQueue(eventQueue)
+ , m_isCancelled(false)
+ {
+ }
+
+ RefPtr<Event> m_event;
+ EventQueue* m_eventQueue;
+ bool m_isCancelled;
+};
+
+void EventQueue::removeEvent(Event* event)
{
- ASSERT(event->target());
- bool wasAdded = m_queuedEvents.add(event).second;
- ASSERT_UNUSED(wasAdded, wasAdded); // It should not have already been in the list.
-
- if (!m_pendingEventTimer->isActive())
- m_pendingEventTimer->startOneShot(0);
+ if (Node* node = event->target()->toNode())
+ m_nodesWithQueuedScrollEvents.remove(node);
+ m_eventTaskMap.remove(event);
}
+void EventQueue::enqueueEvent(PassRefPtr<Event> prpEvent)
+{
+ RefPtr<Event> event = prpEvent;
+ OwnPtr<EventDispatcherTask> task = EventDispatcherTask::create(event, this);
+ m_eventTaskMap.add(event.release(), task.get());
+ m_scriptExecutionContext->postTask(task.release());
+}
+
void EventQueue::enqueueOrDispatchScrollEvent(PassRefPtr<Node> target, ScrollEventTargetType targetType)
{
// Per the W3C CSSOM View Module, scroll events fired at the document should bubble, others should not.
@@ -99,50 +135,22 @@
bool EventQueue::cancelEvent(Event* event)
{
- bool found = m_queuedEvents.contains(event);
- m_queuedEvents.remove(event);
- if (m_queuedEvents.isEmpty())
- m_pendingEventTimer->stop();
- return found;
+ EventDispatcherTask* task = m_eventTaskMap.get(event);
+ if (!task)
+ return false;
+ task->cancel();
+ removeEvent(event);
+ return true;
}
void EventQueue::cancelQueuedEvents()
{
- m_pendingEventTimer->stop();
- m_queuedEvents.clear();
-}
-
-void EventQueue::pendingEventTimerFired()
-{
- ASSERT(!m_pendingEventTimer->isActive());
- ASSERT(!m_queuedEvents.isEmpty());
-
+ for (EventTaskMap::iterator it = m_eventTaskMap.begin(); it != m_eventTaskMap.end(); ++it) {
+ EventDispatcherTask* task = it->second;
+ task->cancel();
+ }
+ m_eventTaskMap.clear();
m_nodesWithQueuedScrollEvents.clear();
-
- // Insert a marker for where we should stop.
- ASSERT(!m_queuedEvents.contains(0));
- bool wasAdded = m_queuedEvents.add(0).second;
- ASSERT_UNUSED(wasAdded, wasAdded); // It should not have already been in the list.
-
- RefPtr<EventQueue> protector(this);
-
- while (!m_queuedEvents.isEmpty()) {
- ListHashSet<RefPtr<Event> >::iterator iter = m_queuedEvents.begin();
- RefPtr<Event> event = *iter;
- m_queuedEvents.remove(iter);
- if (!event)
- break;
- dispatchEvent(event.get());
- }
}
-void EventQueue::dispatchEvent(PassRefPtr<Event> event)
-{
- EventTarget* eventTarget = event->target();
- if (eventTarget->toDOMWindow())
- eventTarget->toDOMWindow()->dispatchEvent(event, 0);
- else
- eventTarget->dispatchEvent(event);
}
-
-}
Modified: trunk/Source/WebCore/dom/EventQueue.h (86837 => 86838)
--- trunk/Source/WebCore/dom/EventQueue.h 2011-05-19 11:47:02 UTC (rev 86837)
+++ trunk/Source/WebCore/dom/EventQueue.h 2011-05-19 12:03:58 UTC (rev 86838)
@@ -27,27 +27,24 @@
#ifndef EventQueue_h
#define EventQueue_h
+#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
-#include <wtf/ListHashSet.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
class Event;
-class EventQueueTimer;
class Node;
class ScriptExecutionContext;
-class EventQueue : public RefCounted<EventQueue> {
+class EventQueue {
public:
enum ScrollEventTargetType {
ScrollEventDocumentTarget,
ScrollEventElementTarget
};
- static PassRefPtr<EventQueue> create(ScriptExecutionContext*);
+ static PassOwnPtr<EventQueue> create(ScriptExecutionContext*);
~EventQueue();
void enqueueEvent(PassRefPtr<Event>);
@@ -58,14 +55,14 @@
private:
explicit EventQueue(ScriptExecutionContext*);
- void pendingEventTimerFired();
- void dispatchEvent(PassRefPtr<Event>);
+ void removeEvent(Event*);
- OwnPtr<EventQueueTimer> m_pendingEventTimer;
- ListHashSet<RefPtr<Event> > m_queuedEvents;
HashSet<Node*> m_nodesWithQueuedScrollEvents;
-
- friend class EventQueueTimer;
+ ScriptExecutionContext* m_scriptExecutionContext;
+
+ class EventDispatcherTask;
+ typedef HashMap<RefPtr<Event>, EventDispatcherTask*> EventTaskMap;
+ EventTaskMap m_eventTaskMap;
};
}
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes