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 "core/workers/WorkerEventQueue.h" 29 30 #include "core/dom/ExecutionContext.h" 31 #include "core/dom/ExecutionContextTask.h" 32 #include "core/events/Event.h" 33 #include "core/inspector/InspectorInstrumentation.h" 34 35 namespace blink { 36 37 PassOwnPtrWillBeRawPtr<WorkerEventQueue> WorkerEventQueue::create(ExecutionContext* context) 38 { 39 return adoptPtrWillBeNoop(new WorkerEventQueue(context)); 40 } 41 42 WorkerEventQueue::WorkerEventQueue(ExecutionContext* context) 43 : m_executionContext(context) 44 , m_isClosed(false) 45 { 46 } 47 48 WorkerEventQueue::~WorkerEventQueue() 49 { 50 ASSERT(m_eventTaskMap.isEmpty()); 51 } 52 53 void WorkerEventQueue::trace(Visitor* visitor) 54 { 55 #if ENABLE(OILPAN) 56 visitor->trace(m_executionContext); 57 visitor->trace(m_eventTaskMap); 58 #endif 59 EventQueue::trace(visitor); 60 } 61 62 class WorkerEventQueue::EventDispatcherTask : public ExecutionContextTask { 63 public: 64 static PassOwnPtr<EventDispatcherTask> create(PassRefPtrWillBeRawPtr<Event> event, WorkerEventQueue* eventQueue) 65 { 66 return adoptPtr(new EventDispatcherTask(event, eventQueue)); 67 } 68 69 virtual ~EventDispatcherTask() 70 { 71 if (m_event) 72 m_eventQueue->removeEvent(m_event.get()); 73 } 74 75 void dispatchEvent(ExecutionContext*, PassRefPtrWillBeRawPtr<Event> event) 76 { 77 event->target()->dispatchEvent(event); 78 } 79 80 virtual void performTask(ExecutionContext* context) 81 { 82 if (m_isCancelled) 83 return; 84 m_eventQueue->removeEvent(m_event.get()); 85 dispatchEvent(context, m_event); 86 m_event.clear(); 87 } 88 89 void cancel() 90 { 91 m_isCancelled = true; 92 m_event.clear(); 93 } 94 95 private: 96 EventDispatcherTask(PassRefPtrWillBeRawPtr<Event> event, WorkerEventQueue* eventQueue) 97 : m_event(event) 98 , m_eventQueue(eventQueue) 99 , m_isCancelled(false) 100 { 101 } 102 103 RefPtrWillBePersistent<Event> m_event; 104 WorkerEventQueue* m_eventQueue; 105 bool m_isCancelled; 106 }; 107 108 void WorkerEventQueue::removeEvent(Event* event) 109 { 110 InspectorInstrumentation::didRemoveEvent(event->target(), event); 111 m_eventTaskMap.remove(event); 112 } 113 114 bool WorkerEventQueue::enqueueEvent(PassRefPtrWillBeRawPtr<Event> prpEvent) 115 { 116 if (m_isClosed) 117 return false; 118 RefPtrWillBeRawPtr<Event> event = prpEvent; 119 InspectorInstrumentation::didEnqueueEvent(event->target(), event.get()); 120 OwnPtr<EventDispatcherTask> task = EventDispatcherTask::create(event, this); 121 m_eventTaskMap.add(event.release(), task.get()); 122 m_executionContext->postTask(task.release()); 123 return true; 124 } 125 126 bool WorkerEventQueue::cancelEvent(Event* event) 127 { 128 EventDispatcherTask* task = m_eventTaskMap.get(event); 129 if (!task) 130 return false; 131 task->cancel(); 132 removeEvent(event); 133 return true; 134 } 135 136 void WorkerEventQueue::close() 137 { 138 m_isClosed = true; 139 for (EventTaskMap::iterator it = m_eventTaskMap.begin(); it != m_eventTaskMap.end(); ++it) { 140 Event* event = it->key.get(); 141 EventDispatcherTask* task = it->value; 142 InspectorInstrumentation::didRemoveEvent(event->target(), event); 143 task->cancel(); 144 } 145 m_eventTaskMap.clear(); 146 } 147 148 } 149