1/* 2 * Copyright (C) 2010 Google Inc. All Rights Reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * 25 */ 26 27#include "config.h" 28#include "WorkerEventQueue.h" 29 30#include "DOMWindow.h" 31#include "Document.h" 32#include "Event.h" 33#include "EventNames.h" 34#include "ScriptExecutionContext.h" 35 36namespace WebCore { 37 38PassOwnPtr<WorkerEventQueue> WorkerEventQueue::create(ScriptExecutionContext* context) 39{ 40 return adoptPtr(new WorkerEventQueue(context)); 41} 42 43WorkerEventQueue::WorkerEventQueue(ScriptExecutionContext* context) 44 : m_scriptExecutionContext(context) 45 , m_isClosed(false) 46{ 47} 48 49WorkerEventQueue::~WorkerEventQueue() 50{ 51 close(); 52} 53 54class WorkerEventQueue::EventDispatcherTask : public ScriptExecutionContext::Task { 55public: 56 static PassOwnPtr<EventDispatcherTask> create(PassRefPtr<Event> event, WorkerEventQueue* eventQueue) 57 { 58 return adoptPtr(new EventDispatcherTask(event, eventQueue)); 59 } 60 61 virtual ~EventDispatcherTask() 62 { 63 if (m_event) 64 m_eventQueue->removeEvent(m_event.get()); 65 } 66 67 void dispatchEvent(ScriptExecutionContext*, PassRefPtr<Event> event) 68 { 69 event->target()->dispatchEvent(event); 70 } 71 72 virtual void performTask(ScriptExecutionContext* context) 73 { 74 if (m_isCancelled) 75 return; 76 m_eventQueue->removeEvent(m_event.get()); 77 dispatchEvent(context, m_event); 78 m_event.clear(); 79 } 80 81 void cancel() 82 { 83 m_isCancelled = true; 84 m_event.clear(); 85 } 86 87private: 88 EventDispatcherTask(PassRefPtr<Event> event, WorkerEventQueue* eventQueue) 89 : m_event(event) 90 , m_eventQueue(eventQueue) 91 , m_isCancelled(false) 92 { 93 } 94 95 RefPtr<Event> m_event; 96 WorkerEventQueue* m_eventQueue; 97 bool m_isCancelled; 98}; 99 100void WorkerEventQueue::removeEvent(Event* event) 101{ 102 m_eventTaskMap.remove(event); 103} 104 105bool WorkerEventQueue::enqueueEvent(PassRefPtr<Event> prpEvent) 106{ 107 if (m_isClosed) 108 return false; 109 RefPtr<Event> event = prpEvent; 110 OwnPtr<EventDispatcherTask> task = EventDispatcherTask::create(event, this); 111 m_eventTaskMap.add(event.release(), task.get()); 112 m_scriptExecutionContext->postTask(task.release()); 113 return true; 114} 115 116bool WorkerEventQueue::cancelEvent(Event* event) 117{ 118 EventDispatcherTask* task = m_eventTaskMap.get(event); 119 if (!task) 120 return false; 121 task->cancel(); 122 removeEvent(event); 123 return true; 124} 125 126void WorkerEventQueue::close() 127{ 128 m_isClosed = true; 129 for (EventTaskMap::iterator it = m_eventTaskMap.begin(); it != m_eventTaskMap.end(); ++it) { 130 EventDispatcherTask* task = it->value; 131 task->cancel(); 132 } 133 m_eventTaskMap.clear(); 134} 135 136} 137