Implement basics of "Terminate Service Worker" algorithm.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 16 Nov 2017 03:05:02 +0000 (03:05 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 16 Nov 2017 03:05:02 +0000 (03:05 +0000)
https://bugs.webkit.org/show_bug.cgi?id=179551

Reviewed by Chris Dumez.

Source/WebCore:

No new tests (No observable behavior change yet).

* workers/WorkerGlobalScope.cpp:
(WebCore::WorkerGlobalScope::stopIndexedDatabase):

* workers/WorkerMessagingProxy.cpp:
(WebCore::WorkerMessagingProxy::workerThreadCreated):
(WebCore::WorkerMessagingProxy::terminateWorkerGlobalScope):

* workers/WorkerThread.cpp:
(WebCore::WorkerThread::workerThread):
(WebCore::WorkerThread::stop):
* workers/WorkerThread.h:

* workers/service/context/SWContextManager.cpp:
(WebCore::SWContextManager::terminateWorker):
* workers/service/context/SWContextManager.h:

* workers/service/server/SWServer.cpp:
(WebCore::SWServer::workerContextTerminated):
(WebCore::SWServer::terminateWorker):
* workers/service/server/SWServer.h:

* workers/service/server/SWServerToContextConnection.cpp:
(WebCore::SWServerToContextConnection::workerTerminated):
* workers/service/server/SWServerToContextConnection.h:

* workers/service/server/SWServerWorker.cpp:
(WebCore::SWServerWorker::terminate):
(WebCore::SWServerWorker::contextTerminated):
* workers/service/server/SWServerWorker.h:

Source/WebKit:

* StorageProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
(WebKit::WebSWServerToContextConnection::terminateWorker):
* StorageProcess/ServiceWorker/WebSWServerToContextConnection.h:
* StorageProcess/ServiceWorker/WebSWServerToContextConnection.messages.in:

* WebProcess/Storage/WebSWContextManagerConnection.cpp:
(WebKit::WebSWContextManagerConnection::terminateWorker):
(WebKit::WebSWContextManagerConnection::workerTerminated):
* WebProcess/Storage/WebSWContextManagerConnection.h:
* WebProcess/Storage/WebSWContextManagerConnection.messages.in:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@224909 268f45cc-cd09-0410-ab3c-d52691b4dbfc

20 files changed:
Source/WebCore/ChangeLog
Source/WebCore/workers/WorkerGlobalScope.cpp
Source/WebCore/workers/WorkerMessagingProxy.cpp
Source/WebCore/workers/WorkerThread.cpp
Source/WebCore/workers/WorkerThread.h
Source/WebCore/workers/service/context/SWContextManager.cpp
Source/WebCore/workers/service/context/SWContextManager.h
Source/WebCore/workers/service/server/SWServer.cpp
Source/WebCore/workers/service/server/SWServer.h
Source/WebCore/workers/service/server/SWServerToContextConnection.cpp
Source/WebCore/workers/service/server/SWServerToContextConnection.h
Source/WebCore/workers/service/server/SWServerWorker.cpp
Source/WebCore/workers/service/server/SWServerWorker.h
Source/WebKit/ChangeLog
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.cpp
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.h
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerToContextConnection.messages.in
Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp
Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h
Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in

index 2245a2b..f9bbf8d 100644 (file)
@@ -1,3 +1,42 @@
+2017-11-15  Brady Eidson  <beidson@apple.com>
+
+        Implement basics of "Terminate Service Worker" algorithm.
+        https://bugs.webkit.org/show_bug.cgi?id=179551
+
+        Reviewed by Chris Dumez.
+
+        No new tests (No observable behavior change yet).
+
+        * workers/WorkerGlobalScope.cpp:
+        (WebCore::WorkerGlobalScope::stopIndexedDatabase):
+
+        * workers/WorkerMessagingProxy.cpp:
+        (WebCore::WorkerMessagingProxy::workerThreadCreated):
+        (WebCore::WorkerMessagingProxy::terminateWorkerGlobalScope):
+
+        * workers/WorkerThread.cpp:
+        (WebCore::WorkerThread::workerThread):
+        (WebCore::WorkerThread::stop):
+        * workers/WorkerThread.h:
+
+        * workers/service/context/SWContextManager.cpp:
+        (WebCore::SWContextManager::terminateWorker):
+        * workers/service/context/SWContextManager.h:
+
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::workerContextTerminated):
+        (WebCore::SWServer::terminateWorker):
+        * workers/service/server/SWServer.h:
+
+        * workers/service/server/SWServerToContextConnection.cpp:
+        (WebCore::SWServerToContextConnection::workerTerminated):
+        * workers/service/server/SWServerToContextConnection.h:
+
+        * workers/service/server/SWServerWorker.cpp:
+        (WebCore::SWServerWorker::terminate):
+        (WebCore::SWServerWorker::contextTerminated):
+        * workers/service/server/SWServerWorker.h:
+
 2017-11-15  Eric Carlson  <eric.carlson@apple.com>
 
         Log media readyState and networkState as strings
index 3ffb38f..8861eb8 100644 (file)
@@ -162,8 +162,8 @@ IDBClient::IDBConnectionProxy* WorkerGlobalScope::idbConnectionProxy()
 void WorkerGlobalScope::stopIndexedDatabase()
 {
 #if ENABLE(INDEXED_DATABASE_IN_WORKERS)
-    ASSERT(m_connectionProxy);
-    m_connectionProxy->forgetActivityForCurrentThread();
+    if (m_connectionProxy)
+        m_connectionProxy->forgetActivityForCurrentThread();
 #endif
 }
 
index a2146cd..b5dd38a 100644 (file)
@@ -192,7 +192,7 @@ void WorkerMessagingProxy::workerThreadCreated(DedicatedWorkerThread& workerThre
 
     if (m_askedToTerminate) {
         // Worker.terminate() could be called from JS before the thread was created.
-        m_workerThread->stop();
+        m_workerThread->stop(nullptr);
     } else {
         ASSERT(!m_unconfirmedMessageCount);
         m_unconfirmedMessageCount = m_queuedEarlyTasks.size();
@@ -268,7 +268,7 @@ void WorkerMessagingProxy::terminateWorkerGlobalScope()
     m_inspectorProxy->workerTerminated();
 
     if (m_workerThread)
-        m_workerThread->stop();
+        m_workerThread->stop(nullptr);
 }
 
 void WorkerMessagingProxy::confirmMessageFromWorkerObject(bool hasPendingActivity)
index 94efa3c..7211bad 100644 (file)
@@ -188,7 +188,7 @@ void WorkerThread::workerThread()
     String exceptionMessage;
     scriptController->evaluate(ScriptSourceCode(m_startupData->m_sourceCode, m_startupData->m_scriptURL), &exceptionMessage);
     
-    RunLoop::main().dispatch([evaluateCallback = WTFMove(m_evaluateCallback), message = exceptionMessage.isolatedCopy()] {
+    callOnMainThread([evaluateCallback = WTFMove(m_evaluateCallback), message = exceptionMessage.isolatedCopy()] {
         if (evaluateCallback)
             evaluateCallback(message);
     });
@@ -228,6 +228,9 @@ void WorkerThread::workerThread()
     // Clean up WebCore::ThreadGlobalData before WTF::Thread goes away!
     threadGlobalData().destroy();
 
+    if (m_stoppedCallback)
+        callOnMainThread(WTFMove(m_stoppedCallback));
+
     // The thread object may be already destroyed from notification now, don't try to access "this".
     protector->detach();
 }
@@ -254,8 +257,11 @@ void WorkerThread::runEventLoop()
     m_runLoop.run(m_workerGlobalScope.get());
 }
 
-void WorkerThread::stop()
+void WorkerThread::stop(WTF::Function<void()>&& stoppedCallback)
 {
+    ASSERT(!m_stoppedCallback);
+    m_stoppedCallback = WTFMove(stoppedCallback);
+
     // Mutex protection is necessary to ensure that m_workerGlobalScope isn't changed by
     // WorkerThread::workerThread() while we're accessing it. Note also that stop() can
     // be called before m_workerGlobalScope is fully created.
index 0c623b2..cc92469 100644 (file)
@@ -64,7 +64,7 @@ public:
     virtual ~WorkerThread();
 
     WEBCORE_EXPORT bool start(WTF::Function<void(const String&)>&& evaluateCallback);
-    void stop();
+    void stop(WTF::Function<void()>&& terminatedCallback);
 
     ThreadIdentifier threadID() const { return m_thread ? m_thread->id() : 0; }
     WorkerRunLoop& runLoop() { return m_runLoop; }
@@ -126,6 +126,8 @@ private:
     RefPtr<IDBClient::IDBConnectionProxy> m_idbConnectionProxy;
 #endif
     RefPtr<SocketProvider> m_socketProvider;
+
+    WTF::Function<void()> m_stoppedCallback;
 };
 
 } // namespace WebCore
index b3ccb63..9ad83a2 100644 (file)
@@ -92,6 +92,18 @@ void SWContextManager::fireActivateEvent(ServiceWorkerIdentifier identifier)
     serviceWorker->thread().fireActivateEvent();
 }
 
+void SWContextManager::terminateWorker(ServiceWorkerIdentifier identifier)
+{
+    auto* serviceWorker = m_workerMap.get(identifier);
+    if (!serviceWorker)
+        return;
+
+    serviceWorker->thread().stop([identifier] {
+        if (auto* connection = SWContextManager::singleton().connection())
+            connection->workerTerminated(identifier);
+    });
+}
+
 } // namespace WebCore
 
 #endif
index 6f291dc..73e9247 100644 (file)
@@ -50,6 +50,7 @@ public:
         virtual void didFinishInstall(ServiceWorkerIdentifier, bool wasSuccessful) = 0;
         virtual void didFinishActivation(ServiceWorkerIdentifier) = 0;
         virtual void setServiceWorkerHasPendingEvents(ServiceWorkerIdentifier, bool) = 0;
+        virtual void workerTerminated(ServiceWorkerIdentifier) = 0;
     };
 
     WEBCORE_EXPORT void setConnection(std::unique_ptr<Connection>&&);
@@ -60,6 +61,7 @@ public:
     WEBCORE_EXPORT void postMessageToServiceWorkerGlobalScope(ServiceWorkerIdentifier destination, Ref<SerializedScriptValue>&& message, ServiceWorkerClientData&& source);
     WEBCORE_EXPORT void fireInstallEvent(ServiceWorkerIdentifier);
     WEBCORE_EXPORT void fireActivateEvent(ServiceWorkerIdentifier);
+    WEBCORE_EXPORT void terminateWorker(ServiceWorkerIdentifier);
 
 private:
     SWContextManager() = default;
index 8619602..4ec19c2 100644 (file)
@@ -272,6 +272,12 @@ void SWServer::didFinishActivation(SWServerWorker& worker)
         SWServerJobQueue::didFinishActivation(*registration, worker.identifier());
 }
 
+void SWServer::workerContextTerminated(SWServerWorker& worker)
+{
+    auto result = m_workersByID.remove(worker.identifier());
+    ASSERT_UNUSED(result, result);
+}
+
 void SWServer::didResolveRegistrationPromise(Connection& connection, const ServiceWorkerRegistrationKey& registrationKey)
 {
     ASSERT_UNUSED(connection, m_connections.contains(connection.identifier()));
@@ -345,6 +351,16 @@ void SWServer::installContextData(const ServiceWorkerContextData& data)
     connection->installServiceWorkerContext(data);
 }
 
+
+void SWServer::terminateWorker(SWServerWorker& worker)
+{
+    auto* connection = SWServerToContextConnection::connectionForIdentifier(worker.contextConnectionIdentifier());
+    if (connection)
+        connection->terminateWorker(worker.identifier());
+    else
+        LOG_ERROR("Request to terminate a worker whose context connection does not exist");
+}
+
 void SWServer::fireInstallEvent(SWServerWorker& worker)
 {
     auto* connection = SWServerToContextConnection::connectionForIdentifier(worker.contextConnectionIdentifier());
index 47c9ab5..9784d74 100644 (file)
@@ -112,6 +112,7 @@ public:
     void postTaskReply(CrossThreadTask&&);
 
     void updateWorker(Connection&, const ServiceWorkerRegistrationKey&, const URL&, const String& script, WorkerType);
+    void terminateWorker(SWServerWorker&);
     void fireInstallEvent(SWServerWorker&);
     void fireActivateEvent(SWServerWorker&);
     SWServerWorker* workerByID(ServiceWorkerIdentifier identifier) const { return m_workersByID.get(identifier); }
@@ -123,6 +124,7 @@ public:
     void scriptContextStarted(SWServerWorker&);
     void didFinishInstall(SWServerWorker&, bool wasSuccessful);
     void didFinishActivation(SWServerWorker&);
+    void workerContextTerminated(SWServerWorker&);
 
     WEBCORE_EXPORT void serverToContextConnectionCreated();
     
index 3fe010f..42d2309 100644 (file)
@@ -102,6 +102,12 @@ void SWServerToContextConnection::setServiceWorkerHasPendingEvents(ServiceWorker
         worker->setHasPendingEvents(hasPendingEvents);
 }
 
+void SWServerToContextConnection::workerTerminated(ServiceWorkerIdentifier serviceWorkerIdentifier)
+{
+    if (auto* worker = SWServerWorker::existingWorkerForIdentifier(serviceWorkerIdentifier))
+        worker->contextTerminated();
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)
index 24a546c..7079fb6 100644 (file)
@@ -46,6 +46,7 @@ public:
     virtual void installServiceWorkerContext(const ServiceWorkerContextData&) = 0;
     virtual void fireInstallEvent(ServiceWorkerIdentifier) = 0;
     virtual void fireActivateEvent(ServiceWorkerIdentifier) = 0;
+    virtual void terminateWorker(ServiceWorkerIdentifier) = 0;
 
     // Messages back from the SW host process
     WEBCORE_EXPORT void scriptContextFailedToStart(ServiceWorkerIdentifier, const String& message);
@@ -53,6 +54,7 @@ public:
     WEBCORE_EXPORT void didFinishInstall(ServiceWorkerIdentifier, bool wasSuccessful);
     WEBCORE_EXPORT void didFinishActivation(ServiceWorkerIdentifier);
     WEBCORE_EXPORT void setServiceWorkerHasPendingEvents(ServiceWorkerIdentifier, bool hasPendingEvents);
+    WEBCORE_EXPORT void workerTerminated(ServiceWorkerIdentifier);
 
     static SWServerToContextConnection* connectionForIdentifier(SWServerToContextConnectionIdentifier);
 
index 007ee9c..c030617 100644 (file)
@@ -62,7 +62,7 @@ SWServerWorker::~SWServerWorker()
 
 void SWServerWorker::terminate()
 {
-    // FIXME: Implement
+    m_server.terminateWorker(*this);
 }
 
 void SWServerWorker::scriptContextFailedToStart(const String& message)
@@ -85,6 +85,11 @@ void SWServerWorker::didFinishActivation()
     m_server.didFinishActivation(*this);
 }
 
+void SWServerWorker::contextTerminated()
+{
+    m_server.workerContextTerminated(*this);
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)
index dd2e8ea..39f76cd 100644 (file)
@@ -70,6 +70,7 @@ public:
     void scriptContextStarted();
     void didFinishInstall(bool wasSuccessful);
     void didFinishActivation();
+    void contextTerminated();
 
     WEBCORE_EXPORT static SWServerWorker* existingWorkerForIdentifier(ServiceWorkerIdentifier);
 
index 79d6455..7950d0c 100644 (file)
@@ -1,3 +1,21 @@
+2017-11-15  Brady Eidson  <beidson@apple.com>
+
+        Implement basics of "Terminate Service Worker" algorithm.
+        https://bugs.webkit.org/show_bug.cgi?id=179551
+
+        Reviewed by Chris Dumez.
+
+        * StorageProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
+        (WebKit::WebSWServerToContextConnection::terminateWorker):
+        * StorageProcess/ServiceWorker/WebSWServerToContextConnection.h:
+        * StorageProcess/ServiceWorker/WebSWServerToContextConnection.messages.in:
+
+        * WebProcess/Storage/WebSWContextManagerConnection.cpp:
+        (WebKit::WebSWContextManagerConnection::terminateWorker):
+        (WebKit::WebSWContextManagerConnection::workerTerminated):
+        * WebProcess/Storage/WebSWContextManagerConnection.h:
+        * WebProcess/Storage/WebSWContextManagerConnection.messages.in:
+
 2017-11-15  Brent Fulgham  <bfulgham@apple.com>
 
         Remove access to 'com.apple.mediaaccessibility.public' preferences in WebContent sandbox
index b82ef35..24e4ada 100644 (file)
@@ -71,6 +71,11 @@ void WebSWServerToContextConnection::fireActivateEvent(ServiceWorkerIdentifier s
     send(Messages::WebSWContextManagerConnection::FireActivateEvent(serviceWorkerIdentifier));
 }
 
+void WebSWServerToContextConnection::terminateWorker(ServiceWorkerIdentifier serviceWorkerIdentifier)
+{
+    send(Messages::WebSWContextManagerConnection::TerminateWorker(serviceWorkerIdentifier));
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(SERVICE_WORKER)
index 87b76d2..b5b8749 100644 (file)
@@ -58,7 +58,8 @@ private:
     void installServiceWorkerContext(const WebCore::ServiceWorkerContextData&) final;
     void fireInstallEvent(WebCore::ServiceWorkerIdentifier) final;
     void fireActivateEvent(WebCore::ServiceWorkerIdentifier) final;
-    
+    void terminateWorker(WebCore::ServiceWorkerIdentifier) final;
+
     Ref<IPC::Connection> m_ipcConnection;
     
 }; // class WebSWServerToContextConnection
index 9dc8c16..67d5bc6 100644 (file)
@@ -29,7 +29,8 @@ messages -> WebSWServerToContextConnection {
     ScriptContextStarted(WebCore::ServiceWorkerIdentifier identifier);
     DidFinishInstall(WebCore::ServiceWorkerIdentifier identifier, bool wasSuccessful);
     DidFinishActivation(WebCore::ServiceWorkerIdentifier identifier);
-    SetServiceWorkerHasPendingEvents(WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, bool hasPendingEvents);
+    SetServiceWorkerHasPendingEvents(WebCore::ServiceWorkerIdentifier identifier, bool hasPendingEvents);
+    WorkerTerminated(WebCore::ServiceWorkerIdentifier identifier);
 }
 
 #endif // ENABLE(SERVICE_WORKER)
index cdd95d8..3de1b05 100644 (file)
@@ -158,6 +158,11 @@ void WebSWContextManagerConnection::fireActivateEvent(ServiceWorkerIdentifier id
     SWContextManager::singleton().fireActivateEvent(identifier);
 }
 
+void WebSWContextManagerConnection::terminateWorker(ServiceWorkerIdentifier identifier)
+{
+    SWContextManager::singleton().terminateWorker(identifier);
+}
+
 void WebSWContextManagerConnection::postMessageToServiceWorkerClient(const ServiceWorkerClientIdentifier& destinationIdentifier, Ref<SerializedScriptValue>&& message, ServiceWorkerIdentifier sourceIdentifier, const String& sourceOrigin)
 {
     m_connectionToStorageProcess->send(Messages::StorageProcess::PostMessageToServiceWorkerClient(destinationIdentifier, IPC::DataReference { message->data() }, sourceIdentifier, sourceOrigin), 0);
@@ -178,6 +183,11 @@ void WebSWContextManagerConnection::setServiceWorkerHasPendingEvents(ServiceWork
     m_connectionToStorageProcess->send(Messages::WebSWServerToContextConnection::SetServiceWorkerHasPendingEvents(serviceWorkerIdentifier, hasPendingEvents), 0);
 }
 
+void WebSWContextManagerConnection::workerTerminated(ServiceWorkerIdentifier serviceWorkerIdentifier)
+{
+    m_connectionToStorageProcess->send(Messages::WebSWServerToContextConnection::WorkerTerminated(serviceWorkerIdentifier), 0);
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SERVICE_WORKER)
index 8e4d56b..f199ce7 100644 (file)
@@ -55,6 +55,7 @@ private:
     void didFinishInstall(WebCore::ServiceWorkerIdentifier, bool wasSuccessful) final;
     void didFinishActivation(WebCore::ServiceWorkerIdentifier) final;
     void setServiceWorkerHasPendingEvents(WebCore::ServiceWorkerIdentifier, bool) final;
+    void workerTerminated(WebCore::ServiceWorkerIdentifier) final;
 
     // IPC messages.
     void serviceWorkerStartedWithMessage(WebCore::ServiceWorkerIdentifier, const String& exceptionMessage) final;
@@ -63,6 +64,7 @@ private:
     void postMessageToServiceWorkerGlobalScope(WebCore::ServiceWorkerIdentifier destinationIdentifier, const IPC::DataReference& message, WebCore::ServiceWorkerClientData&& source);
     void fireInstallEvent(WebCore::ServiceWorkerIdentifier);
     void fireActivateEvent(WebCore::ServiceWorkerIdentifier);
+    void terminateWorker(WebCore::ServiceWorkerIdentifier);
 
     Ref<IPC::Connection> m_connectionToStorageProcess;
     uint64_t m_pageID { 0 };
index 7331a8d..8ab0580 100644 (file)
@@ -28,6 +28,7 @@ messages -> WebSWContextManagerConnection {
     PostMessageToServiceWorkerGlobalScope(WebCore::ServiceWorkerIdentifier destinationIdentifier, IPC::DataReference message, struct WebCore::ServiceWorkerClientData source)
     FireInstallEvent(WebCore::ServiceWorkerIdentifier identifier)
     FireActivateEvent(WebCore::ServiceWorkerIdentifier identifier)
+    TerminateWorker(WebCore::ServiceWorkerIdentifier identifier)
 }
 
 #endif