Changeset 247104 in webkit
- Timestamp:
- Jul 3, 2019 2:16:43 PM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r247102 r247104 1 2019-07-03 Youenn Fablet <youenn@apple.com> 2 3 Strengthen updating/removing of registrations from the database 4 https://bugs.webkit.org/show_bug.cgi?id=199450 5 rdar://problem/51891395 6 7 Reviewed by Chris Dumez. 8 9 SWServerWorker is ref counted and has a ref to its SWServer. 10 There is thus a possibility for SWServerWorker to live longer than its SWServer. 11 To mitigate this, have SWServerWorker use a WeakPtr<SWServer> and 12 check whether SWServer is null when receiving messages from WebProcess. 13 Make also sure that RegistrationStore updated registration map does not get corrupted by checking 14 the registration keys explicitly. 15 16 Covered by existing tests. 17 18 * workers/service/ServiceWorkerRegistrationKey.h: 19 (WebCore::ServiceWorkerRegistrationKey::operator!= const): 20 (WebCore::ServiceWorkerRegistrationKey::isEmpty const): 21 * workers/service/server/RegistrationStore.cpp: 22 (WebCore::RegistrationStore::updateRegistration): 23 (WebCore::RegistrationStore::removeRegistration): 24 (WebCore::RegistrationStore::addRegistrationFromDatabase): 25 * workers/service/server/RegistrationStore.h: 26 * workers/service/server/SWServer.cpp: 27 (WebCore::SWServer::workerByID const): 28 (WebCore::SWServer::removeRegistration): 29 * workers/service/server/SWServer.h: 30 * workers/service/server/SWServerWorker.cpp: 31 (WebCore::SWServerWorker::SWServerWorker): 32 (WebCore::m_scriptResourceMap): 33 (WebCore::SWServerWorker::contextData const): 34 (WebCore::SWServerWorker::terminate): 35 (WebCore::SWServerWorker::scriptContextFailedToStart): 36 (WebCore::SWServerWorker::scriptContextStarted): 37 (WebCore::SWServerWorker::didFinishInstall): 38 (WebCore::SWServerWorker::didFinishActivation): 39 (WebCore::SWServerWorker::contextTerminated): 40 (WebCore::SWServerWorker::findClientByIdentifier const): 41 (WebCore::SWServerWorker::matchAll): 42 (WebCore::SWServerWorker::userAgent const): 43 (WebCore::SWServerWorker::claim): 44 (WebCore::SWServerWorker::skipWaiting): 45 (WebCore::SWServerWorker::setHasPendingEvents): 46 (WebCore::SWServerWorker::setState): 47 * workers/service/server/SWServerWorker.h: 48 (WebCore::SWServerWorker::server): 49 1 50 2019-07-03 Sam Weinig <weinig@apple.com> 2 51 -
trunk/Source/WebCore/workers/service/ServiceWorkerRegistrationKey.h
r239427 r247104 42 42 43 43 bool operator==(const ServiceWorkerRegistrationKey&) const; 44 bool operator!=(const ServiceWorkerRegistrationKey& key) const { return !(*this == key); } 45 bool isEmpty() const { return *this == emptyKey(); } 44 46 WEBCORE_EXPORT bool isMatching(const SecurityOriginData& topOrigin, const URL& clientURL) const; 45 47 bool originIsMatching(const SecurityOriginData& topOrigin, const URL& clientURL) const; -
trunk/Source/WebCore/workers/service/server/RegistrationStore.cpp
r246184 r247104 105 105 void RegistrationStore::updateRegistration(const ServiceWorkerContextData& data) 106 106 { 107 ASSERT(isMainThread()); 108 ASSERT(!data.registration.key.isEmpty()); 109 if (data.registration.key.isEmpty()) 110 return; 111 107 112 m_updatedRegistrations.set(data.registration.key, data); 108 113 scheduleDatabasePushIfNecessary(); 109 114 } 110 115 111 void RegistrationStore::removeRegistration( SWServerRegistration& registration)116 void RegistrationStore::removeRegistration(const ServiceWorkerRegistrationKey& key) 112 117 { 118 ASSERT(isMainThread()); 119 ASSERT(!key.isEmpty()); 120 if (key.isEmpty()) 121 return; 122 113 123 ServiceWorkerContextData contextData; 114 contextData.registration.key = registration.key();115 m_updatedRegistrations.set( registration.key(), WTFMove(contextData));124 contextData.registration.key = key; 125 m_updatedRegistrations.set(key, WTFMove(contextData)); 116 126 scheduleDatabasePushIfNecessary(); 117 127 } 118 128 119 void RegistrationStore::addRegistrationFromDatabase(ServiceWorkerContextData&& context)129 void RegistrationStore::addRegistrationFromDatabase(ServiceWorkerContextData&& data) 120 130 { 121 m_server.addRegistrationFromStore(WTFMove(context)); 131 ASSERT(!data.registration.key.isEmpty()); 132 if (data.registration.key.isEmpty()) 133 return; 134 135 m_server.addRegistrationFromStore(WTFMove(data)); 122 136 } 123 137 -
trunk/Source/WebCore/workers/service/server/RegistrationStore.h
r246184 r247104 58 58 // Callbacks from the SWServer 59 59 void updateRegistration(const ServiceWorkerContextData&); 60 void removeRegistration( SWServerRegistration&);60 void removeRegistration(const ServiceWorkerRegistrationKey&); 61 61 62 62 // Callbacks from the database -
trunk/Source/WebCore/workers/service/server/SWServer.cpp
r246184 r247104 84 84 { 85 85 auto* worker = SWServerWorker::existingWorkerForIdentifier(identifier); 86 ASSERT(!worker || &worker->server() == this);86 ASSERT(!worker || worker->server() == this); 87 87 return worker; 88 88 } … … 178 178 m_originStore->remove(topOrigin); 179 179 if (m_registrationStore) 180 m_registrationStore->removeRegistration( *registration);180 m_registrationStore->removeRegistration(key); 181 181 } 182 182 -
trunk/Source/WebCore/workers/service/server/SWServer.h
r246184 r247104 63 63 class Timer; 64 64 65 class SWServer {65 class SWServer : public CanMakeWeakPtr<SWServer> { 66 66 WTF_MAKE_FAST_ALLOCATED; 67 67 public: -
trunk/Source/WebCore/workers/service/server/SWServerWorker.cpp
r244115 r247104 49 49 // FIXME: Use r-value references for script and contentSecurityPolicy 50 50 SWServerWorker::SWServerWorker(SWServer& server, SWServerRegistration& registration, const URL& scriptURL, const String& script, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicy, String&& referrerPolicy, WorkerType type, ServiceWorkerIdentifier identifier, HashMap<URL, ServiceWorkerContextData::ImportedScript>&& scriptResourceMap) 51 : m_server( server)51 : m_server(makeWeakPtr(server)) 52 52 , m_registrationKey(registration.key()) 53 53 , m_data { identifier, scriptURL, ServiceWorkerState::Redundant, type, registration.identifier() } … … 63 63 ASSERT_UNUSED(result, result.isNewEntry); 64 64 65 ASSERT(m_server .getRegistration(m_registrationKey));65 ASSERT(m_server->getRegistration(m_registrationKey)); 66 66 } 67 67 … … 76 76 ServiceWorkerContextData SWServerWorker::contextData() const 77 77 { 78 auto* registration = m_server .getRegistration(m_registrationKey);78 auto* registration = m_server->getRegistration(m_registrationKey); 79 79 ASSERT(registration); 80 80 81 return { WTF::nullopt, registration->data(), m_data.identifier, m_script, m_contentSecurityPolicy, m_referrerPolicy, m_data.scriptURL, m_data.type, m_server .sessionID(), false, m_scriptResourceMap };81 return { WTF::nullopt, registration->data(), m_data.identifier, m_script, m_contentSecurityPolicy, m_referrerPolicy, m_data.scriptURL, m_data.type, m_server->sessionID(), false, m_scriptResourceMap }; 82 82 } 83 83 … … 85 85 { 86 86 if (isRunning()) 87 m_server .terminateWorker(*this);87 m_server->terminateWorker(*this); 88 88 } 89 89 … … 103 103 void SWServerWorker::scriptContextFailedToStart(const Optional<ServiceWorkerJobDataIdentifier>& jobDataIdentifier, const String& message) 104 104 { 105 m_server.scriptContextFailedToStart(jobDataIdentifier, *this, message); 105 ASSERT(m_server); 106 if (m_server) 107 m_server->scriptContextFailedToStart(jobDataIdentifier, *this, message); 106 108 } 107 109 108 110 void SWServerWorker::scriptContextStarted(const Optional<ServiceWorkerJobDataIdentifier>& jobDataIdentifier) 109 111 { 110 m_server.scriptContextStarted(jobDataIdentifier, *this); 112 ASSERT(m_server); 113 if (m_server) 114 m_server->scriptContextStarted(jobDataIdentifier, *this); 111 115 } 112 116 113 117 void SWServerWorker::didFinishInstall(const Optional<ServiceWorkerJobDataIdentifier>& jobDataIdentifier, bool wasSuccessful) 114 118 { 115 m_server.didFinishInstall(jobDataIdentifier, *this, wasSuccessful); 119 ASSERT(m_server); 120 if (m_server) 121 m_server->didFinishInstall(jobDataIdentifier, *this, wasSuccessful); 116 122 } 117 123 118 124 void SWServerWorker::didFinishActivation() 119 125 { 120 m_server.didFinishActivation(*this); 126 ASSERT(m_server); 127 if (m_server) 128 m_server->didFinishActivation(*this); 121 129 } 122 130 123 131 void SWServerWorker::contextTerminated() 124 132 { 125 m_server.workerContextTerminated(*this); 133 ASSERT(m_server); 134 if (m_server) 135 m_server->workerContextTerminated(*this); 126 136 } 127 137 128 138 Optional<ServiceWorkerClientData> SWServerWorker::findClientByIdentifier(const ServiceWorkerClientIdentifier& clientId) const 129 139 { 130 return m_server.serviceWorkerClientWithOriginByID(origin(), clientId); 140 ASSERT(m_server); 141 if (!m_server) 142 return { }; 143 return m_server->serviceWorkerClientWithOriginByID(origin(), clientId); 131 144 } 132 145 133 146 void SWServerWorker::matchAll(const ServiceWorkerClientQueryOptions& options, ServiceWorkerClientsMatchAllCallback&& callback) 134 147 { 135 return m_server.matchAll(*this, options, WTFMove(callback)); 148 ASSERT(m_server); 149 if (!m_server) 150 return callback({ }); 151 return m_server->matchAll(*this, options, WTFMove(callback)); 136 152 } 137 153 138 154 String SWServerWorker::userAgent() const 139 155 { 140 return m_server.serviceWorkerClientUserAgent(origin()); 156 ASSERT(m_server); 157 if (!m_server) 158 return { }; 159 return m_server->serviceWorkerClientUserAgent(origin()); 141 160 } 142 161 143 162 void SWServerWorker::claim() 144 163 { 145 return m_server.claim(*this); 164 ASSERT(m_server); 165 if (m_server) 166 m_server->claim(*this); 146 167 } 147 168 … … 155 176 m_isSkipWaitingFlagSet = true; 156 177 157 auto* registration = m_server .getRegistration(m_registrationKey);178 auto* registration = m_server->getRegistration(m_registrationKey); 158 179 ASSERT(registration || isTerminating()); 159 180 if (registration) … … 171 192 172 193 // Do tryClear/tryActivate, as per https://w3c.github.io/ServiceWorker/#wait-until-method. 173 auto* registration = m_server .getRegistration(m_registrationKey);194 auto* registration = m_server->getRegistration(m_registrationKey); 174 195 if (!registration) 175 196 return; … … 196 217 m_data.state = state; 197 218 198 auto* registration = m_server .getRegistration(m_registrationKey);219 auto* registration = m_server->getRegistration(m_registrationKey); 199 220 ASSERT(registration || state == ServiceWorkerState::Redundant); 200 221 if (registration) { … … 217 238 void SWServerWorker::setState(State state) 218 239 { 219 ASSERT(state != State::Running || m_server .getRegistration(m_registrationKey));240 ASSERT(state != State::Running || m_server->getRegistration(m_registrationKey)); 220 241 m_state = state; 221 242 } -
trunk/Source/WebCore/workers/service/server/SWServerWorker.h
r244115 r247104 74 74 void setState(State); 75 75 76 SWServer & server() { return m_server; }76 SWServer* server() { return m_server.get(); } 77 77 const ServiceWorkerRegistrationKey& registrationKey() const { return m_registrationKey; } 78 78 const URL& scriptURL() const { return m_data.scriptURL; } … … 118 118 void callWhenActivatedHandler(bool success); 119 119 120 SWServer&m_server;120 WeakPtr<SWServer> m_server; 121 121 ServiceWorkerRegistrationKey m_registrationKey; 122 122 ServiceWorkerData m_data;
Note: See TracChangeset
for help on using the changeset viewer.