2 * Copyright (C) 2017 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
28 #if ENABLE(SERVICE_WORKER)
30 #include "ClientOrigin.h"
31 #include "DocumentIdentifier.h"
32 #include "RegistrationStore.h"
33 #include "SWServerWorker.h"
34 #include "ServiceWorkerClientData.h"
35 #include "ServiceWorkerIdentifier.h"
36 #include "ServiceWorkerJob.h"
37 #include "ServiceWorkerRegistrationData.h"
38 #include "ServiceWorkerRegistrationKey.h"
39 #include "ServiceWorkerTypes.h"
40 #include <wtf/CrossThreadQueue.h>
41 #include <wtf/CrossThreadTask.h>
42 #include <wtf/HashMap.h>
43 #include <wtf/HashSet.h>
44 #include <wtf/ObjectIdentifier.h>
45 #include <wtf/RunLoop.h>
46 #include <wtf/ThreadSafeRefCounted.h>
47 #include <wtf/Threading.h>
48 #include <wtf/UniqueRef.h>
53 class SWServerJobQueue;
54 class SWServerRegistration;
55 class SWServerToContextConnection;
56 enum class ServiceWorkerRegistrationState;
57 enum class ServiceWorkerState;
59 struct ServiceWorkerClientQueryOptions;
60 struct ServiceWorkerContextData;
61 struct ServiceWorkerFetchResult;
62 struct ServiceWorkerRegistrationData;
66 WTF_MAKE_FAST_ALLOCATED;
69 WTF_MAKE_FAST_ALLOCATED;
70 friend class SWServer;
72 WEBCORE_EXPORT virtual ~Connection();
74 using Identifier = SWServerConnectionIdentifier;
75 Identifier identifier() const { return m_identifier; }
77 WEBCORE_EXPORT void didResolveRegistrationPromise(const ServiceWorkerRegistrationKey&);
78 SWServerRegistration* doRegistrationMatching(const SecurityOriginData& topOrigin, const URL& clientURL) { return m_server.doRegistrationMatching(topOrigin, clientURL); }
79 void resolveRegistrationReadyRequests(SWServerRegistration&);
81 // Messages to the client WebProcess
82 virtual void updateRegistrationStateInClient(ServiceWorkerRegistrationIdentifier, ServiceWorkerRegistrationState, const std::optional<ServiceWorkerData>&) = 0;
83 virtual void updateWorkerStateInClient(ServiceWorkerIdentifier, ServiceWorkerState) = 0;
84 virtual void fireUpdateFoundEvent(ServiceWorkerRegistrationIdentifier) = 0;
85 virtual void notifyClientsOfControllerChange(const HashSet<DocumentIdentifier>& contextIdentifiers, const ServiceWorkerData& newController) = 0;
86 virtual void registrationReady(uint64_t registrationReadyRequestIdentifier, ServiceWorkerRegistrationData&&) = 0;
89 WEBCORE_EXPORT explicit Connection(SWServer&);
90 SWServer& server() { return m_server; }
92 WEBCORE_EXPORT void scheduleJobInServer(const ServiceWorkerJobData&);
93 WEBCORE_EXPORT void finishFetchingScriptInServer(const ServiceWorkerFetchResult&);
94 WEBCORE_EXPORT void addServiceWorkerRegistrationInServer(ServiceWorkerRegistrationIdentifier);
95 WEBCORE_EXPORT void removeServiceWorkerRegistrationInServer(ServiceWorkerRegistrationIdentifier);
96 WEBCORE_EXPORT void syncTerminateWorker(ServiceWorkerIdentifier);
97 WEBCORE_EXPORT void whenRegistrationReady(uint64_t registrationReadyRequestIdentifier, const SecurityOriginData& topOrigin, const URL& clientURL);
100 // Messages to the client WebProcess
101 virtual void rejectJobInClient(const ServiceWorkerJobDataIdentifier&, const ExceptionData&) = 0;
102 virtual void resolveRegistrationJobInClient(const ServiceWorkerJobDataIdentifier&, const ServiceWorkerRegistrationData&, ShouldNotifyWhenResolved) = 0;
103 virtual void resolveUnregistrationJobInClient(const ServiceWorkerJobDataIdentifier&, const ServiceWorkerRegistrationKey&, bool registrationResult) = 0;
104 virtual void startScriptFetchInClient(const ServiceWorkerJobDataIdentifier&) = 0;
106 struct RegistrationReadyRequest {
107 SecurityOriginData topOrigin;
113 Identifier m_identifier;
114 Vector<RegistrationReadyRequest> m_registrationReadyRequests;
117 WEBCORE_EXPORT SWServer(UniqueRef<SWOriginStore>&&, String&& registrationDatabaseDirectory, PAL::SessionID);
118 WEBCORE_EXPORT ~SWServer();
120 WEBCORE_EXPORT void clearAll(WTF::CompletionHandler<void()>&&);
121 WEBCORE_EXPORT void clear(const SecurityOrigin&, WTF::CompletionHandler<void()>&&);
123 SWServerRegistration* getRegistration(const ServiceWorkerRegistrationKey&);
124 void addRegistration(std::unique_ptr<SWServerRegistration>&&);
125 void removeRegistration(const ServiceWorkerRegistrationKey&);
126 WEBCORE_EXPORT Vector<ServiceWorkerRegistrationData> getRegistrations(const SecurityOriginData& topOrigin, const URL& clientURL);
128 void scheduleJob(const ServiceWorkerJobData&);
129 void rejectJob(const ServiceWorkerJobData&, const ExceptionData&);
130 void resolveRegistrationJob(const ServiceWorkerJobData&, const ServiceWorkerRegistrationData&, ShouldNotifyWhenResolved);
131 void resolveUnregistrationJob(const ServiceWorkerJobData&, const ServiceWorkerRegistrationKey&, bool unregistrationResult);
132 void startScriptFetch(const ServiceWorkerJobData&);
134 void postTask(CrossThreadTask&&);
135 void postTaskReply(CrossThreadTask&&);
137 void updateWorker(Connection&, const ServiceWorkerJobDataIdentifier&, SWServerRegistration&, const URL&, const String& script, WorkerType);
138 void terminateWorker(SWServerWorker&);
139 void syncTerminateWorker(SWServerWorker&);
140 void fireInstallEvent(SWServerWorker&);
141 void fireActivateEvent(SWServerWorker&);
142 WEBCORE_EXPORT SWServerWorker* workerByID(ServiceWorkerIdentifier) const;
144 WEBCORE_EXPORT void markAllWorkersAsTerminated();
146 Connection* getConnection(SWServerConnectionIdentifier identifier) { return m_connections.get(identifier); }
147 SWOriginStore& originStore() { return m_originStore; }
149 void scriptContextFailedToStart(const std::optional<ServiceWorkerJobDataIdentifier>&, SWServerWorker&, const String& message);
150 void scriptContextStarted(const std::optional<ServiceWorkerJobDataIdentifier>&, SWServerWorker&);
151 void didFinishInstall(const std::optional<ServiceWorkerJobDataIdentifier>&, SWServerWorker&, bool wasSuccessful);
152 void didFinishActivation(SWServerWorker&);
153 void workerContextTerminated(SWServerWorker&);
154 std::optional<ServiceWorkerClientData> findClientByIdentifier(const ClientOrigin&, ServiceWorkerClientIdentifier);
155 void matchAll(SWServerWorker&, const ServiceWorkerClientQueryOptions&, ServiceWorkerClientsMatchAllCallback&&);
156 void claim(SWServerWorker&);
158 WEBCORE_EXPORT void serverToContextConnectionCreated();
160 WEBCORE_EXPORT static HashSet<SWServer*>& allServers();
162 WEBCORE_EXPORT void registerServiceWorkerClient(ClientOrigin&&, ServiceWorkerClientIdentifier, ServiceWorkerClientData&&, const std::optional<ServiceWorkerIdentifier>& controllingServiceWorkerIdentifier);
163 WEBCORE_EXPORT void unregisterServiceWorkerClient(const ClientOrigin&, ServiceWorkerClientIdentifier);
165 using RunServiceWorkerCallback = WTF::Function<void(bool, SWServerToContextConnection&)>;
166 WEBCORE_EXPORT void runServiceWorkerIfNecessary(ServiceWorkerIdentifier, RunServiceWorkerCallback&&);
168 void setClientActiveWorker(ServiceWorkerClientIdentifier, ServiceWorkerIdentifier);
169 void resolveRegistrationReadyRequests(SWServerRegistration&);
171 void addRegistrationFromStore(ServiceWorkerContextData&&);
174 void registerConnection(Connection&);
175 void unregisterConnection(Connection&);
177 void taskThreadEntryPoint();
178 void handleTaskRepliesOnMainThread();
180 void scriptFetchFinished(Connection&, const ServiceWorkerFetchResult&);
182 void didResolveRegistrationPromise(Connection&, const ServiceWorkerRegistrationKey&);
184 void addClientServiceWorkerRegistration(Connection&, ServiceWorkerRegistrationIdentifier);
185 void removeClientServiceWorkerRegistration(Connection&, ServiceWorkerRegistrationIdentifier);
187 WEBCORE_EXPORT SWServerRegistration* doRegistrationMatching(const SecurityOriginData& topOrigin, const URL& clientURL);
188 bool runServiceWorker(ServiceWorkerIdentifier);
190 void tryInstallContextData(ServiceWorkerContextData&&);
191 void installContextData(const ServiceWorkerContextData&);
193 SWServerRegistration* registrationFromServiceWorkerIdentifier(ServiceWorkerIdentifier);
195 enum TerminationMode {
199 void terminateWorkerInternal(SWServerWorker&, TerminationMode);
201 HashMap<SWServerConnectionIdentifier, Connection*> m_connections;
202 HashMap<ServiceWorkerRegistrationKey, std::unique_ptr<SWServerRegistration>> m_registrations;
203 HashMap<ServiceWorkerRegistrationIdentifier, SWServerRegistration*> m_registrationsByID;
204 HashMap<ServiceWorkerRegistrationKey, std::unique_ptr<SWServerJobQueue>> m_jobQueues;
206 HashMap<ServiceWorkerIdentifier, Ref<SWServerWorker>> m_runningOrTerminatingWorkers;
209 Vector<ServiceWorkerClientInformation> clients;
210 std::unique_ptr<Timer> terminateServiceWorkersTimer;
212 HashMap<ClientOrigin, Clients> m_clients;
213 HashMap<ServiceWorkerClientIdentifier, ServiceWorkerIdentifier> m_clientToControllingWorker;
215 RefPtr<Thread> m_taskThread;
216 Lock m_taskThreadLock;
218 CrossThreadQueue<CrossThreadTask> m_taskQueue;
219 CrossThreadQueue<CrossThreadTask> m_taskReplyQueue;
221 Lock m_mainThreadReplyLock;
222 bool m_mainThreadReplyScheduled { false };
223 UniqueRef<SWOriginStore> m_originStore;
224 RegistrationStore m_registrationStore;
225 Deque<ServiceWorkerContextData> m_pendingContextDatas;
226 HashMap<ServiceWorkerIdentifier, Vector<RunServiceWorkerCallback>> m_serviceWorkerRunRequests;
227 PAL::SessionID m_sessionID;
230 } // namespace WebCore
232 #endif // ENABLE(SERVICE_WORKER)