Changeset 224301 in webkit
- Timestamp:
- Nov 1, 2017 3:32:42 PM (6 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 10 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r224299 r224301 1 2017-11-01 Chris Dumez <cdumez@apple.com> 2 3 Split JobQueue logic out of SWServerRegistration 4 https://bugs.webkit.org/show_bug.cgi?id=179126 5 6 Reviewed by Brady Eidson. 7 8 Split JobQueue logic out of SWServerRegistration and into a SWServerJobQueue class to match the Service Workers 9 specification more closely. 10 11 * Sources.txt: 12 * WebCore.xcodeproj/project.pbxproj: 13 * workers/service/ServiceWorkerContainer.cpp: 14 (WebCore::ServiceWorkerContainer::jobResolvedWithRegistration): 15 * workers/service/ServiceWorkerRegistrationData.cpp: 16 (WebCore::ServiceWorkerRegistrationData::isolatedCopy const): 17 * workers/service/ServiceWorkerRegistrationData.h: 18 (WebCore::ServiceWorkerRegistrationData::encode const): 19 (WebCore::ServiceWorkerRegistrationData::decode): 20 * workers/service/server/SWServer.cpp: 21 (WebCore::SWServer::~SWServer): 22 (WebCore::SWServer::getRegistration): 23 (WebCore::SWServer::addRegistration): 24 (WebCore::SWServer::removeRegistration): 25 (WebCore::SWServer::Connection::scriptContextStarted): 26 (WebCore::SWServer::scheduleJob): 27 (WebCore::SWServer::scriptFetchFinished): 28 (WebCore::SWServer::scriptContextFailedToStart): 29 (WebCore::SWServer::scriptContextStarted): 30 * workers/service/server/SWServer.h: 31 * workers/service/server/SWServerJobQueue.cpp: Added. 32 (WebCore::SWServerJobQueue::SWServerJobQueue): 33 (WebCore::SWServerJobQueue::~SWServerJobQueue): 34 (WebCore::SWServerJobQueue::enqueueJob): 35 (WebCore::SWServerJobQueue::scriptFetchFinished): 36 (WebCore::SWServerJobQueue::scriptContextFailedToStart): 37 (WebCore::SWServerJobQueue::scriptContextStarted): 38 (WebCore::SWServerJobQueue::startNextJob): 39 (WebCore::SWServerJobQueue::runRegisterJob): 40 (WebCore::SWServerJobQueue::runUnregisterJob): 41 (WebCore::SWServerJobQueue::runUpdateJob): 42 (WebCore::SWServerJobQueue::rejectWithExceptionOnMainThread): 43 (WebCore::SWServerJobQueue::resolveWithRegistrationOnMainThread): 44 (WebCore::SWServerJobQueue::resolveCurrentRegistrationJobOnMainThead): 45 (WebCore::SWServerJobQueue::resolveWithUnregistrationResultOnMainThread): 46 (WebCore::SWServerJobQueue::startScriptFetchFromMainThread): 47 (WebCore::SWServerJobQueue::rejectCurrentJob): 48 (WebCore::SWServerJobQueue::resolveCurrentRegistrationJob): 49 (WebCore::SWServerJobQueue::resolveCurrentUnregistrationJob): 50 (WebCore::SWServerJobQueue::startScriptFetchForCurrentJob): 51 (WebCore::SWServerJobQueue::finishCurrentJob): 52 * workers/service/server/SWServerJobQueue.h: Added. 53 * workers/service/server/SWServerRegistration.cpp: 54 (WebCore::SWServerRegistration::SWServerRegistration): 55 (WebCore::SWServerRegistration::~SWServerRegistration): 56 (WebCore::SWServerRegistration::data const): 57 * workers/service/server/SWServerRegistration.h: 58 (WebCore::SWServerRegistration::key const): 59 (WebCore::SWServerRegistration::isUninstalling const): 60 (WebCore::SWServerRegistration::setIsUninstalling): 61 (WebCore::SWServerRegistration::setLastUpdateTime): 62 (WebCore::SWServerRegistration::updateViaCache const): 63 (WebCore::SWServerRegistration::setActiveServiceWorkerIdentifier): 64 1 65 2017-11-01 Daniel Bates <dabates@apple.com> 2 66 -
trunk/Source/WebCore/Sources.txt
r224244 r224301 2175 2175 workers/service/server/SWClientConnection.cpp 2176 2176 workers/service/server/SWServer.cpp 2177 workers/service/server/SWServerJobQueue.cpp 2177 2178 workers/service/server/SWServerRegistration.cpp 2178 2179 workers/service/server/SWServerWorker.cpp -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r224267 r224301 2169 2169 830A36BD1DAC5FAD006D7D09 /* JSMouseEventInit.h in Headers */ = {isa = PBXBuildFile; fileRef = 830A36BB1DAC5FA7006D7D09 /* JSMouseEventInit.h */; }; 2170 2170 83102B271F9EADD900E404B9 /* JSExtendableMessageEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 83102B231F9EADC200E404B9 /* JSExtendableMessageEvent.h */; }; 2171 8311C0031FAA2E9500E3C8E5 /* SWServerJobQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 8311C0021FAA2E8900E3C8E5 /* SWServerJobQueue.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2171 2172 83120C711C56F3FB001CB112 /* HTMLDataElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 834B86A71C56E83A00F3F0E3 /* HTMLDataElement.h */; }; 2172 2173 8321507E1F27EA1B0095B136 /* NavigatorBeacon.h in Headers */ = {isa = PBXBuildFile; fileRef = 8321507B1F27EA150095B136 /* NavigatorBeacon.h */; }; … … 9374 9375 83102B231F9EADC200E404B9 /* JSExtendableMessageEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSExtendableMessageEvent.h; sourceTree = "<group>"; }; 9375 9376 83102B251F9EADC200E404B9 /* JSExtendableMessageEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSExtendableMessageEvent.cpp; sourceTree = "<group>"; }; 9377 8311C0001FAA2E8900E3C8E5 /* SWServerJobQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SWServerJobQueue.cpp; sourceTree = "<group>"; }; 9378 8311C0021FAA2E8900E3C8E5 /* SWServerJobQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SWServerJobQueue.h; sourceTree = "<group>"; }; 9376 9379 831C46C31F9EE5E000EBD450 /* JSExtendableMessageEventCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSExtendableMessageEventCustom.cpp; sourceTree = "<group>"; }; 9377 9380 831D1F291C56ECA000F5F6C0 /* HTMLDataElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLDataElement.cpp; sourceTree = "<group>"; }; … … 17133 17136 517A52EF1F47535900DCDC0A /* SWServer.cpp */, 17134 17137 517A52EE1F47535900DCDC0A /* SWServer.h */, 17138 8311C0001FAA2E8900E3C8E5 /* SWServerJobQueue.cpp */, 17139 8311C0021FAA2E8900E3C8E5 /* SWServerJobQueue.h */, 17135 17140 51F645951F4A686100B54DED /* SWServerRegistration.cpp */, 17136 17141 51F645941F4A684F00B54DED /* SWServerRegistration.h */, … … 29289 29294 46658DC91FA24B8700F7DD54 /* SWContextManager.h in Headers */, 29290 29295 517A52F01F47535B00DCDC0A /* SWServer.h in Headers */, 29296 8311C0031FAA2E9500E3C8E5 /* SWServerJobQueue.h in Headers */, 29291 29297 51F645971F4A686F00B54DED /* SWServerRegistration.h in Headers */, 29292 29298 517A53461F50C17F00DCDC0A /* SWServerWorker.h in Headers */, -
trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp
r224218 r224301 245 245 // FIXME: Implement proper selection of service workers. 246 246 auto* activeServiceWorker = context->activeServiceWorker(); 247 if (!activeServiceWorker || activeServiceWorker->identifier() != data. identifier) {248 context->setActiveServiceWorker(ServiceWorker::create(*context, data. identifier, data.scriptURL));247 if (!activeServiceWorker || activeServiceWorker->identifier() != data.activeServiceWorkerIdentifier) { 248 context->setActiveServiceWorker(ServiceWorker::create(*context, data.activeServiceWorkerIdentifier, data.scriptURL)); 249 249 activeServiceWorker = context->activeServiceWorker(); 250 250 } -
trunk/Source/WebCore/workers/service/ServiceWorkerRegistrationData.cpp
r224218 r224301 36 36 key.isolatedCopy(), 37 37 identifier, 38 activeServiceWorkerIdentifier, 38 39 scopeURL.isolatedCopy(), 39 40 scriptURL.isolatedCopy(), -
trunk/Source/WebCore/workers/service/ServiceWorkerRegistrationData.h
r224218 r224301 37 37 ServiceWorkerRegistrationKey key; 38 38 uint64_t identifier; 39 uint64_t activeServiceWorkerIdentifier; // FIXME: This should not be part of registrationData. 39 40 URL scopeURL; 40 41 URL scriptURL; … … 51 52 void ServiceWorkerRegistrationData::encode(Encoder& encoder) const 52 53 { 53 encoder << key << identifier << scopeURL << scriptURL << updateViaCache;54 encoder << key << identifier << activeServiceWorkerIdentifier << scopeURL << scriptURL << updateViaCache; 54 55 } 55 56 … … 65 66 decoder >> identifier; 66 67 if (!identifier) 68 return std::nullopt; 69 70 std::optional<uint64_t> activeServiceWorkerIdentifier; 71 decoder >> activeServiceWorkerIdentifier; 72 if (!activeServiceWorkerIdentifier) 67 73 return std::nullopt; 68 74 … … 82 88 return std::nullopt; 83 89 84 return { { WTFMove(*key), WTFMove(*identifier), WTFMove(* scopeURL), WTFMove(*scriptURL), WTFMove(*updateViaCache) } };90 return { { WTFMove(*key), WTFMove(*identifier), WTFMove(*activeServiceWorkerIdentifier), WTFMove(*scopeURL), WTFMove(*scriptURL), WTFMove(*updateViaCache) } }; 85 91 } 86 92 -
trunk/Source/WebCore/workers/service/server/SWServer.cpp
r224295 r224301 32 32 #include "ExceptionData.h" 33 33 #include "Logging.h" 34 #include "SWServerJobQueue.h" 34 35 #include "SWServerRegistration.h" 35 36 #include "SWServerWorker.h" … … 58 59 RELEASE_ASSERT(m_connections.isEmpty()); 59 60 RELEASE_ASSERT(m_registrations.isEmpty()); 61 RELEASE_ASSERT(m_jobQueues.isEmpty()); 60 62 61 63 ASSERT(m_taskQueue.isEmpty()); … … 69 71 } 70 72 73 SWServerRegistration* SWServer::getRegistration(const ServiceWorkerRegistrationKey& registrationKey) 74 { 75 ASSERT(!isMainThread()); 76 return m_registrations.get(registrationKey); 77 } 78 79 void SWServer::addRegistration(std::unique_ptr<SWServerRegistration>&& registration) 80 { 81 ASSERT(!isMainThread()); 82 auto key = registration->key(); 83 m_registrations.add(key, WTFMove(registration)); 84 } 85 86 void SWServer::removeRegistration(const ServiceWorkerRegistrationKey& registrationKey) 87 { 88 ASSERT(!isMainThread()); 89 m_registrations.remove(registrationKey); 90 } 91 71 92 void SWServer::Connection::scheduleJobInServer(const ServiceWorkerJobData& jobData) 72 93 { … … 87 108 } 88 109 89 void SWServer::Connection::scriptContextStarted(const ServiceWorkerRegistrationKey& registrationKey, uint64_t identifier, const String& workerID)90 { 91 m_server.scriptContextStarted(*this, registrationKey, identifier, workerID);110 void SWServer::Connection::scriptContextStarted(const ServiceWorkerRegistrationKey& registrationKey, uint64_t serviceWorkerIdentifier, const String& workerID) 111 { 112 m_server.scriptContextStarted(*this, registrationKey, serviceWorkerIdentifier, workerID); 92 113 } 93 114 … … 103 124 ASSERT(m_connections.contains(jobData.connectionIdentifier())); 104 125 105 auto result = m_ registrations.add(jobData.registrationKey(), nullptr);126 auto result = m_jobQueues.add(jobData.registrationKey(), nullptr); 106 127 if (result.isNewEntry) 107 result.iterator->value = std::make_unique<SWServer Registration>(*this, jobData.registrationKey());128 result.iterator->value = std::make_unique<SWServerJobQueue>(*this, jobData.registrationKey()); 108 129 109 130 ASSERT(result.iterator->value); … … 157 178 ASSERT(m_connections.contains(result.connectionIdentifier)); 158 179 159 auto registration = m_registrations.get(result.registrationKey);160 if (! registration)161 return; 162 163 registration->scriptFetchFinished(connection, result);180 auto jobQueue = m_jobQueues.get(result.registrationKey); 181 if (!jobQueue) 182 return; 183 184 jobQueue->scriptFetchFinished(connection, result); 164 185 } 165 186 … … 168 189 ASSERT(m_connections.contains(connection.identifier())); 169 190 170 if (auto* registration = m_registrations.get(registrationKey))171 registration->scriptContextFailedToStart(connection, workerID, message);172 } 173 174 void SWServer::scriptContextStarted(Connection& connection, const ServiceWorkerRegistrationKey& registrationKey, uint64_t identifier, const String& workerID)191 if (auto* jobQueue = m_jobQueues.get(registrationKey)) 192 jobQueue->scriptContextFailedToStart(connection, workerID, message); 193 } 194 195 void SWServer::scriptContextStarted(Connection& connection, const ServiceWorkerRegistrationKey& registrationKey, uint64_t serviceWorkerIdentifier, const String& workerID) 175 196 { 176 197 ASSERT(m_connections.contains(connection.identifier())); 177 198 178 if (auto* registration = m_registrations.get(registrationKey))179 registration->scriptContextStarted(connection, identifier, workerID);199 if (auto* jobQueue = m_jobQueues.get(registrationKey)) 200 jobQueue->scriptContextStarted(connection, serviceWorkerIdentifier, workerID); 180 201 } 181 202 -
trunk/Source/WebCore/workers/service/server/SWServer.h
r224295 r224301 41 41 namespace WebCore { 42 42 43 class SWServerJobQueue; 43 44 class SWServerRegistration; 44 45 class SWServerWorker; … … 56 57 57 58 WEBCORE_EXPORT void scriptContextFailedToStart(const ServiceWorkerRegistrationKey&, const String& workerID, const String& message); 58 WEBCORE_EXPORT void scriptContextStarted(const ServiceWorkerRegistrationKey&, uint64_t identifier, const String& workerID);59 WEBCORE_EXPORT void scriptContextStarted(const ServiceWorkerRegistrationKey&, uint64_t serviceWorkerIdentifier, const String& workerID); 59 60 60 61 protected: … … 81 82 WEBCORE_EXPORT ~SWServer(); 82 83 84 SWServerRegistration* getRegistration(const ServiceWorkerRegistrationKey&); 85 void addRegistration(std::unique_ptr<SWServerRegistration>&&); 86 void removeRegistration(const ServiceWorkerRegistrationKey&); 87 83 88 void scheduleJob(const ServiceWorkerJobData&); 84 89 void rejectJob(const ServiceWorkerJobData&, const ExceptionData&); … … 101 106 void scriptFetchFinished(Connection&, const ServiceWorkerFetchResult&); 102 107 void scriptContextFailedToStart(Connection&, const ServiceWorkerRegistrationKey&, const String& workerID, const String& message); 103 void scriptContextStarted(Connection&, const ServiceWorkerRegistrationKey&, uint64_t identifier, const String& workerID);108 void scriptContextStarted(Connection&, const ServiceWorkerRegistrationKey&, uint64_t serviceWorkerIdentifier, const String& workerID); 104 109 105 110 HashMap<uint64_t, Connection*> m_connections; 106 111 HashMap<ServiceWorkerRegistrationKey, std::unique_ptr<SWServerRegistration>> m_registrations; 112 HashMap<ServiceWorkerRegistrationKey, std::unique_ptr<SWServerJobQueue>> m_jobQueues; 107 113 108 114 HashMap<String, Ref<SWServerWorker>> m_workersByID; -
trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp
r224299 r224301 25 25 26 26 #include "config.h" 27 #include "SWServer Registration.h"27 #include "SWServerJobQueue.h" 28 28 29 29 #if ENABLE(SERVICE_WORKER) … … 40 40 namespace WebCore { 41 41 42 SWServer Registration::SWServerRegistration(SWServer& server, const ServiceWorkerRegistrationKey& key)43 : m_jobTimer(*this, &SWServer Registration::startNextJob)42 SWServerJobQueue::SWServerJobQueue(SWServer& server, const ServiceWorkerRegistrationKey& key) 43 : m_jobTimer(*this, &SWServerJobQueue::startNextJob) 44 44 , m_server(server) 45 45 , m_registrationKey(key) … … 47 47 } 48 48 49 SWServer Registration::~SWServerRegistration()49 SWServerJobQueue::~SWServerJobQueue() 50 50 { 51 51 ASSERT(m_jobQueue.isEmpty()); 52 52 } 53 53 54 void SWServer Registration::enqueueJob(const ServiceWorkerJobData& jobData)54 void SWServerJobQueue::enqueueJob(const ServiceWorkerJobData& jobData) 55 55 { 56 56 // FIXME: Per the spec, check if this job is equivalent to the last job on the queue. … … 66 66 } 67 67 68 void SWServerRegistration::scriptFetchFinished(SWServer::Connection& connection, const ServiceWorkerFetchResult& result) 69 { 68 void SWServerJobQueue::scriptFetchFinished(SWServer::Connection& connection, const ServiceWorkerFetchResult& result) 69 { 70 ASSERT(isMainThread()); 70 71 ASSERT(m_currentJob && m_currentJob->identifier() == result.jobIdentifier); 71 72 72 73 if (!result.scriptError.isNull()) { 73 74 rejectCurrentJob(ExceptionData { UnknownError, makeString("Script URL ", m_currentJob->scriptURL.string(), " fetch resulted in error: ", result.scriptError.localizedDescription()) }); 74 75 75 76 // If newestWorker is null, invoke Clear Registration algorithm passing this registration as its argument. 76 77 // FIXME: We don't have "clear registration" yet. … … 79 80 } 80 81 81 m_lastUpdateTime = currentTime();82 83 82 // FIXME: If the script data matches byte-for-byte with the existing newestWorker, 84 83 // then resolve and finish the job without doing anything further. … … 88 87 } 89 88 90 void SWServerRegistration::scriptContextFailedToStart(SWServer::Connection&, const String& workerID, const String& message) 91 { 89 void SWServerJobQueue::scriptContextFailedToStart(SWServer::Connection&, const String& workerID, const String& message) 90 { 91 ASSERT(isMainThread()); 92 92 // FIXME: Install has failed. Run the install failed substeps 93 93 // Run the Update Worker State algorithm passing registration’s installing worker and redundant as the arguments. … … 99 99 } 100 100 101 void SWServerRegistration::scriptContextStarted(SWServer::Connection&, uint64_t identifier, const String& workerID) 102 { 101 void SWServerJobQueue::scriptContextStarted(SWServer::Connection&, uint64_t serviceWorkerIdentifier, const String& workerID) 102 { 103 ASSERT(isMainThread()); 103 104 UNUSED_PARAM(workerID); 104 resolveCurrentRegistrationJob(ServiceWorkerRegistrationData { m_registrationKey, identifier, m_scopeURL, m_scriptURL, m_updateViaCache.value_or(ServiceWorkerUpdateViaCache::Imports) }); 105 } 106 107 void SWServerRegistration::startNextJob() 105 106 m_server.postTask(createCrossThreadTask(*this, &SWServerJobQueue::resolveCurrentRegistrationJobOnMainThead, serviceWorkerIdentifier)); 107 } 108 109 void SWServerJobQueue::startNextJob() 108 110 { 109 111 ASSERT(isMainThread()); … … 115 117 switch (m_currentJob->type) { 116 118 case ServiceWorkerJobType::Register: 117 m_server.postTask(createCrossThreadTask(*this, &SWServer Registration::runRegisterJob, *m_currentJob));119 m_server.postTask(createCrossThreadTask(*this, &SWServerJobQueue::runRegisterJob, *m_currentJob)); 118 120 return; 119 121 case ServiceWorkerJobType::Unregister: 120 m_server.postTask(createCrossThreadTask(*this, &SWServer Registration::runUnregisterJob, *m_currentJob));122 m_server.postTask(createCrossThreadTask(*this, &SWServerJobQueue::runUnregisterJob, *m_currentJob)); 121 123 return; 122 124 } … … 125 127 } 126 128 127 bool SWServerRegistration::isEmpty() 128 { 129 ASSERT(!isMainThread()); 130 131 // Having or not-having an m_updateViaCache flag is currently 132 // the signal as to whether or not this is an empty (i.e. "new") registration. 133 // There will be a more explicit signal in the near future. 134 return !m_updateViaCache; 135 } 136 137 SWServerWorker* SWServerRegistration::getNewestWorker() 138 { 139 ASSERT(!isMainThread()); 140 if (m_installingWorker) 141 return m_installingWorker.get(); 142 if (m_waitingWorker) 143 return m_waitingWorker.get(); 144 145 return m_activeWorker.get(); 146 } 147 148 void SWServerRegistration::runRegisterJob(const ServiceWorkerJobData& job) 129 void SWServerJobQueue::runRegisterJob(const ServiceWorkerJobData& job) 149 130 { 150 131 ASSERT(!isMainThread()); … … 163 144 164 145 // If registration is not null (in our parlance "empty"), then: 165 if (!isEmpty()) { 166 ASSERT(m_updateViaCache); 167 168 m_uninstalling = false; 169 auto* newestWorker = getNewestWorker(); 170 if (newestWorker && equalIgnoringFragmentIdentifier(job.scriptURL, newestWorker->scriptURL()) && job.registrationOptions.updateViaCache == *m_updateViaCache) { 171 resolveWithRegistrationOnMainThread(); 146 if (auto* registration = m_server.getRegistration(m_registrationKey)) { 147 registration->setIsUninstalling(false); 148 auto* newestWorker = registration->getNewestWorker(); 149 if (newestWorker && equalIgnoringFragmentIdentifier(job.scriptURL, newestWorker->scriptURL()) && job.registrationOptions.updateViaCache == registration->updateViaCache()) { 150 resolveWithRegistrationOnMainThread(*registration); 172 151 return; 173 152 } 174 153 } else { 175 m_scopeURL = job.scopeURL.isolatedCopy(); 176 m_scopeURL.removeFragmentIdentifier(); 177 m_scriptURL = job.scriptURL.isolatedCopy(); 178 m_updateViaCache = job.registrationOptions.updateViaCache; 154 auto newRegistration = std::make_unique<SWServerRegistration>(m_registrationKey, job.registrationOptions.updateViaCache, job.scopeURL, job.scriptURL); 155 m_server.addRegistration(WTFMove(newRegistration)); 179 156 } 180 157 … … 182 159 } 183 160 184 void SWServerRegistration::runUnregisterJob(const ServiceWorkerJobData& job) 185 { 161 void SWServerJobQueue::runUnregisterJob(const ServiceWorkerJobData& job) 162 { 163 ASSERT(!isMainThread()); 164 186 165 // If the origin of job’s scope url is not job's client's origin, then: 187 166 if (!protocolHostAndPortAreEqual(job.scopeURL, job.clientCreationURL)) … … 189 168 190 169 // Let registration be the result of running "Get Registration" algorithm passing job’s scope url as the argument. 170 auto* registration = m_server.getRegistration(m_registrationKey); 171 191 172 // If registration is null, then: 192 if ( isEmpty() || m_uninstalling) {173 if (!registration || registration->isUninstalling()) { 193 174 // Invoke Resolve Job Promise with job and false. 194 175 resolveWithUnregistrationResultOnMainThread(false); … … 197 178 198 179 // Set registration’s uninstalling flag. 199 m_uninstalling = true;180 registration->setIsUninstalling(true); 200 181 201 182 // Invoke Resolve Job Promise with job and true. … … 205 186 } 206 187 207 void SWServerRegistration::runUpdateJob(const ServiceWorkerJobData& job) 208 { 188 void SWServerJobQueue::runUpdateJob(const ServiceWorkerJobData& job) 189 { 190 auto* registration = m_server.getRegistration(m_registrationKey); 191 209 192 // If registration is null (in our parlance "empty") or registration’s uninstalling flag is set, then: 210 if ( isEmpty())193 if (!registration) 211 194 return rejectWithExceptionOnMainThread(ExceptionData { TypeError, ASCIILiteral("Cannot update a null/nonexistent service worker registration") }); 212 if ( m_uninstalling)195 if (registration->isUninstalling()) 213 196 return rejectWithExceptionOnMainThread(ExceptionData { TypeError, ASCIILiteral("Cannot update a service worker registration that is uninstalling") }); 214 197 215 198 // If job’s job type is update, and newestWorker’s script url does not equal job’s script url with the exclude fragments flag set, then: 216 auto* newestWorker = getNewestWorker();199 auto* newestWorker = registration->getNewestWorker(); 217 200 if (newestWorker && !equalIgnoringFragmentIdentifier(job.scriptURL, newestWorker->scriptURL())) 218 201 return rejectWithExceptionOnMainThread(ExceptionData { TypeError, ASCIILiteral("Cannot update a service worker with a requested script URL whose newest worker has a different script URL") }); … … 221 204 } 222 205 223 void SWServerRegistration::rejectWithExceptionOnMainThread(const ExceptionData& exception) 224 { 225 ASSERT(!isMainThread()); 226 m_server.postTaskReply(createCrossThreadTask(*this, &SWServerRegistration::rejectCurrentJob, exception)); 227 } 228 229 void SWServerRegistration::resolveWithRegistrationOnMainThread() 230 { 231 ASSERT(!isMainThread()); 232 m_server.postTaskReply(createCrossThreadTask(*this, &SWServerRegistration::resolveCurrentRegistrationJob, data())); 233 } 234 235 void SWServerRegistration::resolveWithUnregistrationResultOnMainThread(bool unregistrationResult) 236 { 237 ASSERT(!isMainThread()); 238 m_server.postTaskReply(createCrossThreadTask(*this, &SWServerRegistration::resolveCurrentUnregistrationJob, unregistrationResult)); 239 } 240 241 void SWServerRegistration::startScriptFetchFromMainThread() 242 { 243 ASSERT(!isMainThread()); 244 m_server.postTaskReply(createCrossThreadTask(*this, &SWServerRegistration::startScriptFetchForCurrentJob)); 245 } 246 247 void SWServerRegistration::rejectCurrentJob(const ExceptionData& exceptionData) 206 void SWServerJobQueue::rejectWithExceptionOnMainThread(const ExceptionData& exception) 207 { 208 ASSERT(!isMainThread()); 209 m_server.postTaskReply(createCrossThreadTask(*this, &SWServerJobQueue::rejectCurrentJob, exception)); 210 } 211 212 void SWServerJobQueue::resolveWithRegistrationOnMainThread(SWServerRegistration& registration) 213 { 214 ASSERT(!isMainThread()); 215 m_server.postTaskReply(createCrossThreadTask(*this, &SWServerJobQueue::resolveCurrentRegistrationJob, registration.data())); 216 } 217 218 void SWServerJobQueue::resolveCurrentRegistrationJobOnMainThead(uint64_t serviceWorkerIdentifier) 219 { 220 ASSERT(!isMainThread()); 221 auto* registration = m_server.getRegistration(m_registrationKey); 222 ASSERT(registration); 223 registration->setActiveServiceWorkerIdentifier(serviceWorkerIdentifier); 224 resolveWithRegistrationOnMainThread(*registration); 225 } 226 227 void SWServerJobQueue::resolveWithUnregistrationResultOnMainThread(bool unregistrationResult) 228 { 229 ASSERT(!isMainThread()); 230 m_server.postTaskReply(createCrossThreadTask(*this, &SWServerJobQueue::resolveCurrentUnregistrationJob, unregistrationResult)); 231 } 232 233 void SWServerJobQueue::startScriptFetchFromMainThread() 234 { 235 ASSERT(!isMainThread()); 236 m_server.postTaskReply(createCrossThreadTask(*this, &SWServerJobQueue::startScriptFetchForCurrentJob)); 237 } 238 239 void SWServerJobQueue::rejectCurrentJob(const ExceptionData& exceptionData) 248 240 { 249 241 ASSERT(isMainThread()); … … 255 247 } 256 248 257 void SWServer Registration::resolveCurrentRegistrationJob(const ServiceWorkerRegistrationData& data)249 void SWServerJobQueue::resolveCurrentRegistrationJob(const ServiceWorkerRegistrationData& data) 258 250 { 259 251 ASSERT(isMainThread()); … … 266 258 } 267 259 268 void SWServer Registration::resolveCurrentUnregistrationJob(bool unregistrationResult)260 void SWServerJobQueue::resolveCurrentUnregistrationJob(bool unregistrationResult) 269 261 { 270 262 ASSERT(isMainThread()); … … 277 269 } 278 270 279 void SWServer Registration::startScriptFetchForCurrentJob()271 void SWServerJobQueue::startScriptFetchForCurrentJob() 280 272 { 281 273 ASSERT(isMainThread()); … … 285 277 } 286 278 287 void SWServerRegistration::finishCurrentJob() 288 { 279 void SWServerJobQueue::finishCurrentJob() 280 { 281 ASSERT(isMainThread()); 289 282 ASSERT(m_currentJob); 290 283 ASSERT(!m_jobTimer.isActive()); … … 297 290 } 298 291 299 ServiceWorkerRegistrationData SWServerRegistration::data() const300 {301 return { m_registrationKey, identifier(), m_scopeURL, m_scriptURL, m_updateViaCache.value_or(ServiceWorkerUpdateViaCache::Imports) };302 }303 304 305 292 } // namespace WebCore 306 293 -
trunk/Source/WebCore/workers/service/server/SWServerJobQueue.h
r224299 r224301 30 30 #include "SWServer.h" 31 31 #include "ServiceWorkerJobData.h" 32 #include "ServiceWorkerRegistrationData.h"33 32 #include "Timer.h" 34 33 #include <wtf/Deque.h> 35 #include <wtf/Identified.h>36 34 37 35 namespace WebCore { 38 36 39 class SWServer; 40 class SWServerWorker; 41 struct ExceptionData; 42 struct ServiceWorkerFetchResult; 43 44 class SWServerRegistration : public ThreadSafeIdentified<SWServerRegistration> { 37 class SWServerJobQueue { 45 38 public: 46 explicit SWServer Registration(SWServer&, const ServiceWorkerRegistrationKey&);47 SWServer Registration(const SWServerRegistration&) = delete;48 ~SWServer Registration();39 explicit SWServerJobQueue(SWServer&, const ServiceWorkerRegistrationKey&); 40 SWServerJobQueue(const SWServerRegistration&) = delete; 41 ~SWServerJobQueue(); 49 42 50 43 void enqueueJob(const ServiceWorkerJobData&); 51 44 void scriptFetchFinished(SWServer::Connection&, const ServiceWorkerFetchResult&); 52 45 void scriptContextFailedToStart(SWServer::Connection&, const String& workerID, const String& message); 53 void scriptContextStarted(SWServer::Connection&, uint64_t identifier, const String& workerID); 54 55 ServiceWorkerRegistrationData data() const; 46 void scriptContextStarted(SWServer::Connection&, uint64_t serviceWorkerIdentifier, const String& workerID); 56 47 57 48 private: … … 69 60 70 61 void rejectWithExceptionOnMainThread(const ExceptionData&); 71 void resolveWithRegistrationOnMainThread(); 62 void resolveWithRegistrationOnMainThread(SWServerRegistration&); 63 void resolveCurrentRegistrationJobOnMainThead(uint64_t serviceWorkerIdentifier); 72 64 void resolveWithUnregistrationResultOnMainThread(bool); 73 65 void startScriptFetchFromMainThread(); 74 66 bool isEmpty(); 75 SWServerWorker* getNewestWorker();76 67 77 68 Deque<ServiceWorkerJobData> m_jobQueue; 78 69 std::unique_ptr<ServiceWorkerJobData> m_currentJob; 79 80 bool m_uninstalling { false };81 std::unique_ptr<SWServerWorker> m_installingWorker;82 std::unique_ptr<SWServerWorker> m_waitingWorker;83 std::unique_ptr<SWServerWorker> m_activeWorker;84 URL m_scopeURL;85 URL m_scriptURL;86 std::optional<ServiceWorkerUpdateViaCache> m_updateViaCache;87 88 double m_lastUpdateTime { 0 };89 70 90 71 Timer m_jobTimer; -
trunk/Source/WebCore/workers/service/server/SWServerRegistration.cpp
r224295 r224301 40 40 namespace WebCore { 41 41 42 SWServerRegistration::SWServerRegistration(SWServer& server, const ServiceWorkerRegistrationKey& key) 43 : m_jobTimer(*this, &SWServerRegistration::startNextJob) 44 , m_server(server) 45 , m_registrationKey(key) 42 SWServerRegistration::SWServerRegistration(const ServiceWorkerRegistrationKey& key, ServiceWorkerUpdateViaCache updateViaCache, const URL& scopeURL, const URL& scriptURL) 43 : m_registrationKey(key) 44 , m_updateViaCache(updateViaCache) 45 , m_scopeURL(scopeURL.isolatedCopy()) 46 , m_scriptURL(scriptURL.isolatedCopy()) 46 47 { 48 m_scopeURL.removeFragmentIdentifier(); 47 49 } 48 50 49 51 SWServerRegistration::~SWServerRegistration() 50 52 { 51 ASSERT(m_jobQueue.isEmpty());52 }53 54 void SWServerRegistration::enqueueJob(const ServiceWorkerJobData& jobData)55 {56 // FIXME: Per the spec, check if this job is equivalent to the last job on the queue.57 // If it is, stack it along with that job.58 59 m_jobQueue.append(jobData);60 61 if (m_currentJob)62 return;63 64 if (!m_jobTimer.isActive())65 m_jobTimer.startOneShot(0_s);66 }67 68 void SWServerRegistration::scriptFetchFinished(SWServer::Connection& connection, const ServiceWorkerFetchResult& result)69 {70 ASSERT(m_currentJob && m_currentJob->identifier() == result.jobIdentifier);71 72 if (!result.scriptError.isNull()) {73 rejectCurrentJob(ExceptionData { UnknownError, makeString("Script URL ", m_currentJob->scriptURL.string(), " fetch resulted in error: ", result.scriptError.localizedDescription()) });74 75 // If newestWorker is null, invoke Clear Registration algorithm passing this registration as its argument.76 // FIXME: We don't have "clear registration" yet.77 78 return;79 }80 81 m_lastUpdateTime = currentTime();82 83 // FIXME: If the script data matches byte-for-byte with the existing newestWorker,84 // then resolve and finish the job without doing anything further.85 86 // FIXME: Support the proper worker type (classic vs module)87 m_server.updateWorker(connection, m_registrationKey, m_currentJob->scriptURL, result.script, WorkerType::Classic);88 }89 90 void SWServerRegistration::scriptContextFailedToStart(SWServer::Connection&, const String& workerID, const String& message)91 {92 // FIXME: Install has failed. Run the install failed substeps93 // Run the Update Worker State algorithm passing registration’s installing worker and redundant as the arguments.94 // Run the Update Registration State algorithm passing registration, "installing" and null as the arguments.95 // If newestWorker is null, invoke Clear Registration algorithm passing registration as its argument.96 97 UNUSED_PARAM(workerID);98 UNUSED_PARAM(message);99 }100 101 void SWServerRegistration::scriptContextStarted(SWServer::Connection&, uint64_t identifier, const String& workerID)102 {103 UNUSED_PARAM(workerID);104 resolveCurrentRegistrationJob(ServiceWorkerRegistrationData { m_registrationKey, identifier, m_scopeURL, m_scriptURL, m_updateViaCache.value_or(ServiceWorkerUpdateViaCache::Imports) });105 }106 107 void SWServerRegistration::startNextJob()108 {109 ASSERT(isMainThread());110 ASSERT(!m_currentJob);111 ASSERT(!m_jobQueue.isEmpty());112 113 m_currentJob = std::make_unique<ServiceWorkerJobData>(m_jobQueue.takeFirst().isolatedCopy());114 115 switch (m_currentJob->type) {116 case ServiceWorkerJobType::Register:117 m_server.postTask(createCrossThreadTask(*this, &SWServerRegistration::runRegisterJob, *m_currentJob));118 return;119 case ServiceWorkerJobType::Unregister:120 m_server.postTask(createCrossThreadTask(*this, &SWServerRegistration::runUnregisterJob, *m_currentJob));121 return;122 }123 124 RELEASE_ASSERT_NOT_REACHED();125 }126 127 bool SWServerRegistration::isEmpty()128 {129 ASSERT(!isMainThread());130 131 // Having or not-having an m_updateViaCache flag is currently132 // the signal as to whether or not this is an empty (i.e. "new") registration.133 // There will be a more explicit signal in the near future.134 return !m_updateViaCache;135 53 } 136 54 … … 146 64 } 147 65 148 void SWServerRegistration::runRegisterJob(const ServiceWorkerJobData& job)149 {150 ASSERT(!isMainThread());151 ASSERT(job.type == ServiceWorkerJobType::Register);152 153 if (!shouldTreatAsPotentiallyTrustworthy(job.scriptURL))154 return rejectWithExceptionOnMainThread(ExceptionData { SecurityError, ASCIILiteral("Script URL is not potentially trustworthy") });155 156 // If the origin of job’s script url is not job’s referrer's origin, then:157 if (!protocolHostAndPortAreEqual(job.scriptURL, job.clientCreationURL))158 return rejectWithExceptionOnMainThread(ExceptionData { SecurityError, ASCIILiteral("Script origin does not match the registering client's origin") });159 160 // If the origin of job’s scope url is not job’s referrer's origin, then:161 if (!protocolHostAndPortAreEqual(job.scopeURL, job.clientCreationURL))162 return rejectWithExceptionOnMainThread(ExceptionData { SecurityError, ASCIILiteral("Scope origin does not match the registering client's origin") });163 164 // If registration is not null (in our parlance "empty"), then:165 if (!isEmpty()) {166 ASSERT(m_updateViaCache);167 168 m_uninstalling = false;169 auto* newestWorker = getNewestWorker();170 if (newestWorker && equalIgnoringFragmentIdentifier(job.scriptURL, newestWorker->scriptURL()) && job.registrationOptions.updateViaCache == *m_updateViaCache) {171 resolveWithRegistrationOnMainThread();172 return;173 }174 } else {175 m_scopeURL = job.scopeURL.isolatedCopy();176 m_scopeURL.removeFragmentIdentifier();177 m_scriptURL = job.scriptURL.isolatedCopy();178 m_updateViaCache = job.registrationOptions.updateViaCache;179 }180 181 runUpdateJob(job);182 }183 184 void SWServerRegistration::runUnregisterJob(const ServiceWorkerJobData& job)185 {186 // If the origin of job’s scope url is not job's client's origin, then:187 if (!protocolHostAndPortAreEqual(job.scopeURL, job.clientCreationURL))188 return rejectWithExceptionOnMainThread(ExceptionData { SecurityError, ASCIILiteral("Origin of scope URL does not match the client's origin") });189 190 // Let registration be the result of running "Get Registration" algorithm passing job’s scope url as the argument.191 // If registration is null, then:192 if (isEmpty() || m_uninstalling) {193 // Invoke Resolve Job Promise with job and false.194 resolveWithUnregistrationResultOnMainThread(false);195 return;196 }197 198 // Set registration’s uninstalling flag.199 m_uninstalling = true;200 201 // Invoke Resolve Job Promise with job and true.202 resolveWithUnregistrationResultOnMainThread(true);203 204 // FIXME: Invoke Try Clear Registration with registration.205 }206 207 void SWServerRegistration::runUpdateJob(const ServiceWorkerJobData& job)208 {209 // If registration is null (in our parlance "empty") or registration’s uninstalling flag is set, then:210 if (isEmpty())211 return rejectWithExceptionOnMainThread(ExceptionData { TypeError, ASCIILiteral("Cannot update a null/nonexistent service worker registration") });212 if (m_uninstalling)213 return rejectWithExceptionOnMainThread(ExceptionData { TypeError, ASCIILiteral("Cannot update a service worker registration that is uninstalling") });214 215 // If job’s job type is update, and newestWorker’s script url does not equal job’s script url with the exclude fragments flag set, then:216 auto* newestWorker = getNewestWorker();217 if (newestWorker && !equalIgnoringFragmentIdentifier(job.scriptURL, newestWorker->scriptURL()))218 return rejectWithExceptionOnMainThread(ExceptionData { TypeError, ASCIILiteral("Cannot update a service worker with a requested script URL whose newest worker has a different script URL") });219 220 startScriptFetchFromMainThread();221 }222 223 void SWServerRegistration::rejectWithExceptionOnMainThread(const ExceptionData& exception)224 {225 ASSERT(!isMainThread());226 m_server.postTaskReply(createCrossThreadTask(*this, &SWServerRegistration::rejectCurrentJob, exception));227 }228 229 void SWServerRegistration::resolveWithRegistrationOnMainThread()230 {231 ASSERT(!isMainThread());232 m_server.postTaskReply(createCrossThreadTask(*this, &SWServerRegistration::resolveCurrentRegistrationJob, data()));233 }234 235 void SWServerRegistration::resolveWithUnregistrationResultOnMainThread(bool unregistrationResult)236 {237 ASSERT(!isMainThread());238 m_server.postTaskReply(createCrossThreadTask(*this, &SWServerRegistration::resolveCurrentUnregistrationJob, unregistrationResult));239 }240 241 void SWServerRegistration::startScriptFetchFromMainThread()242 {243 ASSERT(!isMainThread());244 m_server.postTaskReply(createCrossThreadTask(*this, &SWServerRegistration::startScriptFetchForCurrentJob));245 }246 247 void SWServerRegistration::rejectCurrentJob(const ExceptionData& exceptionData)248 {249 ASSERT(isMainThread());250 ASSERT(m_currentJob);251 252 m_server.rejectJob(*m_currentJob, exceptionData);253 254 finishCurrentJob();255 }256 257 void SWServerRegistration::resolveCurrentRegistrationJob(const ServiceWorkerRegistrationData& data)258 {259 ASSERT(isMainThread());260 ASSERT(m_currentJob);261 ASSERT(m_currentJob->type == ServiceWorkerJobType::Register);262 263 m_server.resolveRegistrationJob(*m_currentJob, data);264 265 finishCurrentJob();266 }267 268 void SWServerRegistration::resolveCurrentUnregistrationJob(bool unregistrationResult)269 {270 ASSERT(isMainThread());271 ASSERT(m_currentJob);272 ASSERT(m_currentJob->type == ServiceWorkerJobType::Unregister);273 274 m_server.resolveUnregistrationJob(*m_currentJob, m_registrationKey, unregistrationResult);275 276 finishCurrentJob();277 }278 279 void SWServerRegistration::startScriptFetchForCurrentJob()280 {281 ASSERT(isMainThread());282 ASSERT(m_currentJob);283 284 m_server.startScriptFetch(*m_currentJob);285 }286 287 void SWServerRegistration::finishCurrentJob()288 {289 ASSERT(m_currentJob);290 ASSERT(!m_jobTimer.isActive());291 292 m_currentJob = nullptr;293 if (m_jobQueue.isEmpty())294 return;295 296 startNextJob();297 }298 299 66 ServiceWorkerRegistrationData SWServerRegistration::data() const 300 67 { 301 return { m_registrationKey, identifier(), m_ scopeURL, m_scriptURL, m_updateViaCache.value_or(ServiceWorkerUpdateViaCache::Imports)};68 return { m_registrationKey, identifier(), m_activeServiceWorkerIdentifier, m_scopeURL, m_scriptURL, m_updateViaCache }; 302 69 } 303 304 70 305 71 } // namespace WebCore -
trunk/Source/WebCore/workers/service/server/SWServerRegistration.h
r224218 r224301 29 29 30 30 #include "SWServer.h" 31 #include "ServiceWorkerJobData.h"32 31 #include "ServiceWorkerRegistrationData.h" 33 #include "Timer.h"34 #include <wtf/Deque.h>35 32 #include <wtf/Identified.h> 36 33 37 34 namespace WebCore { 38 35 39 class SWServer;40 36 class SWServerWorker; 41 37 struct ExceptionData; … … 44 40 class SWServerRegistration : public ThreadSafeIdentified<SWServerRegistration> { 45 41 public: 46 explicit SWServerRegistration(SWServer&, const ServiceWorkerRegistrationKey&); 47 SWServerRegistration(const SWServerRegistration&) = delete; 42 SWServerRegistration(const ServiceWorkerRegistrationKey&, ServiceWorkerUpdateViaCache, const URL& scopeURL, const URL& scriptURL); 48 43 ~SWServerRegistration(); 49 44 50 void enqueueJob(const ServiceWorkerJobData&); 51 void scriptFetchFinished(SWServer::Connection&, const ServiceWorkerFetchResult&); 52 void scriptContextFailedToStart(SWServer::Connection&, const String& workerID, const String& message); 53 void scriptContextStarted(SWServer::Connection&, uint64_t identifier, const String& workerID); 54 45 const ServiceWorkerRegistrationKey& key() const { return m_registrationKey; } 46 47 SWServerWorker* getNewestWorker(); 55 48 ServiceWorkerRegistrationData data() const; 56 49 50 bool isUninstalling() const { return m_uninstalling; } 51 void setIsUninstalling(bool value) { m_uninstalling = value; } 52 53 void setLastUpdateTime(double time) { m_lastUpdateTime = time; } 54 ServiceWorkerUpdateViaCache updateViaCache() const { return m_updateViaCache; } 55 56 void setActiveServiceWorkerIdentifier(uint64_t identifier) { m_activeServiceWorkerIdentifier = identifier; } 57 57 58 private: 58 void jobTimerFired(); 59 void startNextJob(); 60 void rejectCurrentJob(const ExceptionData&); 61 void resolveCurrentRegistrationJob(const ServiceWorkerRegistrationData&); 62 void resolveCurrentUnregistrationJob(bool unregistrationResult); 63 void startScriptFetchForCurrentJob(); 64 void finishCurrentJob(); 65 66 void runRegisterJob(const ServiceWorkerJobData&); 67 void runUnregisterJob(const ServiceWorkerJobData&); 68 void runUpdateJob(const ServiceWorkerJobData&); 69 70 void rejectWithExceptionOnMainThread(const ExceptionData&); 71 void resolveWithRegistrationOnMainThread(); 72 void resolveWithUnregistrationResultOnMainThread(bool); 73 void startScriptFetchFromMainThread(); 74 bool isEmpty(); 75 SWServerWorker* getNewestWorker(); 76 77 Deque<ServiceWorkerJobData> m_jobQueue; 78 std::unique_ptr<ServiceWorkerJobData> m_currentJob; 59 ServiceWorkerRegistrationKey m_registrationKey; 60 ServiceWorkerUpdateViaCache m_updateViaCache; 61 URL m_scopeURL; 62 URL m_scriptURL; 79 63 80 64 bool m_uninstalling { false }; … … 82 66 std::unique_ptr<SWServerWorker> m_waitingWorker; 83 67 std::unique_ptr<SWServerWorker> m_activeWorker; 84 URL m_scopeURL; 85 URL m_scriptURL; 86 std::optional<ServiceWorkerUpdateViaCache> m_updateViaCache; 87 68 69 uint64_t m_activeServiceWorkerIdentifier { 0 }; 70 88 71 double m_lastUpdateTime { 0 }; 89 90 Timer m_jobTimer;91 SWServer& m_server;92 ServiceWorkerRegistrationKey m_registrationKey;93 72 }; 94 73
Note: See TracChangeset
for help on using the changeset viewer.