1/*
2 * Copyright (C) 2008-2017 Apple 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#pragma once
27
28#include "WorkerRunLoop.h"
29#include <JavaScriptCore/RuntimeFlags.h>
30#include <memory>
31#include <wtf/Forward.h>
32#include <wtf/Function.h>
33#include <wtf/RefCounted.h>
34
35namespace PAL {
36class SessionID;
37}
38
39namespace WebCore {
40
41class ContentSecurityPolicyResponseHeaders;
42class NotificationClient;
43class SecurityOrigin;
44class SocketProvider;
45class WorkerGlobalScope;
46class WorkerLoaderProxy;
47class WorkerDebuggerProxy;
48class WorkerReportingProxy;
49
50enum class WorkerThreadStartMode {
51 Normal,
52 WaitForInspector,
53};
54
55namespace IDBClient {
56class IDBConnectionProxy;
57}
58
59struct WorkerThreadStartupData;
60
61class WorkerThread : public ThreadSafeRefCounted<WorkerThread> {
62public:
63 virtual ~WorkerThread();
64
65 static HashSet<WorkerThread*>& workerThreads(const LockHolder&);
66 static Lock& workerThreadsMutex();
67
68 WEBCORE_EXPORT void start(WTF::Function<void(const String&)>&& evaluateCallback);
69 void stop(WTF::Function<void()>&& terminatedCallback);
70
71 Thread* thread() const { return m_thread.get(); }
72 WorkerRunLoop& runLoop() { return m_runLoop; }
73 WorkerLoaderProxy& workerLoaderProxy() const { return m_workerLoaderProxy; }
74 WorkerDebuggerProxy& workerDebuggerProxy() const { return m_workerDebuggerProxy; }
75 WorkerReportingProxy& workerReportingProxy() const { return m_workerReportingProxy; }
76
77 // Number of active worker threads.
78 WEBCORE_EXPORT static unsigned workerThreadCount();
79 static void releaseFastMallocFreeMemoryInAllThreads();
80
81#if ENABLE(NOTIFICATIONS)
82 NotificationClient* getNotificationClient() { return m_notificationClient; }
83 void setNotificationClient(NotificationClient* client) { m_notificationClient = client; }
84#endif
85
86 void startRunningDebuggerTasks();
87 void stopRunningDebuggerTasks();
88
89 JSC::RuntimeFlags runtimeFlags() const { return m_runtimeFlags; }
90
91 String identifier() const { return m_identifier; }
92
93protected:
94 WorkerThread(const URL&, const String& name, const String& identifier, const String& userAgent, bool isOnline, const String& sourceCode, WorkerLoaderProxy&, WorkerDebuggerProxy&, WorkerReportingProxy&, WorkerThreadStartMode, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, const SecurityOrigin& topOrigin, MonotonicTime timeOrigin, IDBClient::IDBConnectionProxy*, SocketProvider*, JSC::RuntimeFlags, PAL::SessionID);
95
96 // Factory method for creating a new worker context for the thread.
97 virtual Ref<WorkerGlobalScope> createWorkerGlobalScope(const URL&, Ref<SecurityOrigin>&&, const String& name, const String& identifier, const String& userAgent, bool isOnline, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, Ref<SecurityOrigin>&& topOrigin, MonotonicTime timeOrigin, PAL::SessionID) = 0;
98
99 // Executes the event loop for the worker thread. Derived classes can override to perform actions before/after entering the event loop.
100 virtual void runEventLoop();
101
102 WorkerGlobalScope* workerGlobalScope() { return m_workerGlobalScope.get(); }
103
104 IDBClient::IDBConnectionProxy* idbConnectionProxy();
105 SocketProvider* socketProvider();
106
107private:
108 void workerThread();
109 virtual bool isServiceWorkerThread() const { return false; }
110
111 RefPtr<Thread> m_thread;
112 String m_identifier;
113 WorkerRunLoop m_runLoop;
114 WorkerLoaderProxy& m_workerLoaderProxy;
115 WorkerDebuggerProxy& m_workerDebuggerProxy;
116 WorkerReportingProxy& m_workerReportingProxy;
117 JSC::RuntimeFlags m_runtimeFlags;
118 bool m_pausedForDebugger { false };
119
120 RefPtr<WorkerGlobalScope> m_workerGlobalScope;
121 Lock m_threadCreationAndWorkerGlobalScopeMutex;
122
123 std::unique_ptr<WorkerThreadStartupData> m_startupData;
124
125 WTF::Function<void(const String&)> m_evaluateCallback;
126
127#if ENABLE(NOTIFICATIONS)
128 NotificationClient* m_notificationClient { nullptr };
129#endif
130
131#if ENABLE(INDEXED_DATABASE)
132 RefPtr<IDBClient::IDBConnectionProxy> m_idbConnectionProxy;
133#endif
134 RefPtr<SocketProvider> m_socketProvider;
135
136 WTF::Function<void()> m_stoppedCallback;
137};
138
139} // namespace WebCore
140