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 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 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#include "config.h"
27#include "WorkerEventQueue.h"
28
29#include "Event.h"
30#include "EventTarget.h"
31#include "ScriptExecutionContext.h"
32
33namespace WebCore {
34
35WorkerEventQueue::WorkerEventQueue(ScriptExecutionContext& context)
36 : m_scriptExecutionContext(context)
37{
38}
39
40WorkerEventQueue::~WorkerEventQueue()
41{
42 close();
43}
44
45class WorkerEventQueue::EventDispatcher
46{
47public:
48 EventDispatcher(RefPtr<Event>&& event, WorkerEventQueue& eventQueue)
49 : m_event(WTFMove(event))
50 , m_eventQueue(eventQueue)
51 {
52 }
53
54 ~EventDispatcher()
55 {
56 if (m_event)
57 m_eventQueue.m_eventDispatcherMap.remove(m_event.get());
58 }
59
60 void dispatch()
61 {
62 if (m_isCancelled)
63 return;
64 m_eventQueue.m_eventDispatcherMap.remove(m_event.get());
65 m_event->target()->dispatchEvent(*m_event);
66 m_event = nullptr;
67 }
68
69 void cancel()
70 {
71 m_isCancelled = true;
72 m_event = nullptr;
73 }
74
75private:
76 RefPtr<Event> m_event;
77 WorkerEventQueue& m_eventQueue;
78 bool m_isCancelled { false };
79};
80
81bool WorkerEventQueue::enqueueEvent(Ref<Event>&& event)
82{
83 if (m_isClosed)
84 return false;
85
86 auto* eventPtr = event.ptr();
87 auto eventDispatcher = std::make_unique<EventDispatcher>(WTFMove(event), *this);
88 m_eventDispatcherMap.add(eventPtr, eventDispatcher.get());
89 m_scriptExecutionContext.postTask([eventDispatcher = WTFMove(eventDispatcher)] (ScriptExecutionContext&) {
90 eventDispatcher->dispatch();
91 });
92
93 return true;
94}
95
96bool WorkerEventQueue::cancelEvent(Event& event)
97{
98 EventDispatcher* task = m_eventDispatcherMap.take(&event);
99 if (!task)
100 return false;
101 task->cancel();
102 return true;
103}
104
105void WorkerEventQueue::close()
106{
107 m_isClosed = true;
108 for (auto& dispatcher : m_eventDispatcherMap.values())
109 dispatcher->cancel();
110 m_eventDispatcherMap.clear();
111}
112
113} // namespace WebCore
114