Modified: trunk/Source/WebCore/workers/service/server/SWServer.cpp (224340 => 224341)
--- trunk/Source/WebCore/workers/service/server/SWServer.cpp 2017-11-02 17:24:02 UTC (rev 224340)
+++ trunk/Source/WebCore/workers/service/server/SWServer.cpp 2017-11-02 17:38:57 UTC (rev 224341)
@@ -116,17 +116,21 @@
});
}
+// https://w3c.github.io/ServiceWorker/#schedule-job-algorithm
void SWServer::scheduleJob(const ServiceWorkerJobData& jobData)
{
ASSERT(m_connections.contains(jobData.connectionIdentifier()));
- auto result = m_jobQueues.add(jobData.registrationKey(), nullptr);
- if (result.isNewEntry)
- result.iterator->value = std::make_unique<SWServerJobQueue>(*this, jobData.registrationKey());
+ // FIXME: Per the spec, check if this job is equivalent to the last job on the queue.
+ // If it is, stack it along with that job.
- ASSERT(result.iterator->value);
+ auto& jobQueue = *m_jobQueues.ensure(jobData.registrationKey(), [this, &jobData] {
+ return std::make_unique<SWServerJobQueue>(*this, jobData.registrationKey());
+ }).iterator->value;
- result.iterator->value->enqueueJob(jobData);
+ jobQueue.enqueueJob(jobData);
+ if (jobQueue.size() == 1)
+ jobQueue.runNextJob();
}
void SWServer::rejectJob(const ServiceWorkerJobData& jobData, const ExceptionData& exceptionData)
Modified: trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp (224340 => 224341)
--- trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp 2017-11-02 17:24:02 UTC (rev 224340)
+++ trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp 2017-11-02 17:38:57 UTC (rev 224341)
@@ -40,7 +40,7 @@
namespace WebCore {
SWServerJobQueue::SWServerJobQueue(SWServer& server, const ServiceWorkerRegistrationKey& key)
- : m_jobTimer(*this, &SWServerJobQueue::startNextJob)
+ : m_jobTimer(*this, &SWServerJobQueue::runNextJobSynchronously)
, m_server(server)
, m_registrationKey(key)
{
@@ -51,29 +51,16 @@
ASSERT(m_jobQueue.isEmpty());
}
-void SWServerJobQueue::enqueueJob(const ServiceWorkerJobData& jobData)
-{
- // FIXME: Per the spec, check if this job is equivalent to the last job on the queue.
- // If it is, stack it along with that job.
-
- m_jobQueue.append(jobData);
-
- if (m_currentJob)
- return;
-
- if (!m_jobTimer.isActive())
- m_jobTimer.startOneShot(0_s);
-}
-
void SWServerJobQueue::scriptFetchFinished(SWServer::Connection& connection, const ServiceWorkerFetchResult& result)
{
- ASSERT(m_currentJob && m_currentJob->identifier() == result.jobIdentifier);
+ auto& job = firstJob();
+ ASSERT(job.identifier() == result.jobIdentifier);
auto* registration = m_server.getRegistration(m_registrationKey);
ASSERT(registration);
if (!result.scriptError.isNull()) {
- rejectCurrentJob(ExceptionData { UnknownError, makeString("Script URL ", m_currentJob->scriptURL.string(), " fetch resulted in error: ", result.scriptError.localizedDescription()) });
+ rejectCurrentJob(ExceptionData { UnknownError, makeString("Script URL ", job.scriptURL.string(), " fetch resulted in error: ", result.scriptError.localizedDescription()) });
// If newestWorker is null, invoke Clear Registration algorithm passing this registration as its argument.
if (!registration->getNewestWorker())
@@ -86,7 +73,7 @@
// then resolve and finish the job without doing anything further.
// FIXME: Support the proper worker type (classic vs module)
- m_server.updateWorker(connection, m_registrationKey, m_currentJob->scriptURL, result.script, WorkerType::Classic);
+ m_server.updateWorker(connection, m_registrationKey, job.scriptURL, result.script, WorkerType::Classic);
}
void SWServerJobQueue::scriptContextFailedToStart(SWServer::Connection&, const String& workerID, const String& message)
@@ -107,22 +94,28 @@
auto* registration = m_server.getRegistration(m_registrationKey);
ASSERT(registration);
registration->setActiveServiceWorkerIdentifier(serviceWorkerIdentifier);
- resolveCurrentRegistrationJob(registration->data());
+
+ m_server.resolveRegistrationJob(firstJob(), registration->data());
+ finishCurrentJob();
}
-void SWServerJobQueue::startNextJob()
+// https://w3c.github.io/ServiceWorker/#run-job
+void SWServerJobQueue::runNextJob()
{
- ASSERT(!m_currentJob);
ASSERT(!m_jobQueue.isEmpty());
+ ASSERT(!m_jobTimer.isActive());
+ m_jobTimer.startOneShot(0_s);
+}
- m_currentJob = std::make_unique<ServiceWorkerJobData>(m_jobQueue.takeFirst());
-
- switch (m_currentJob->type) {
+void SWServerJobQueue::runNextJobSynchronously()
+{
+ auto& job = firstJob();
+ switch (job.type) {
case ServiceWorkerJobType::Register:
- runRegisterJob(*m_currentJob);
+ runRegisterJob(job);
return;
case ServiceWorkerJobType::Unregister:
- runUnregisterJob(*m_currentJob);
+ runUnregisterJob(job);
return;
}
@@ -129,6 +122,7 @@
RELEASE_ASSERT_NOT_REACHED();
}
+// https://w3c.github.io/ServiceWorker/#register-algorithm
void SWServerJobQueue::runRegisterJob(const ServiceWorkerJobData& job)
{
ASSERT(job.type == ServiceWorkerJobType::Register);
@@ -149,7 +143,8 @@
registration->setIsUninstalling(false);
auto* newestWorker = registration->getNewestWorker();
if (newestWorker && equalIgnoringFragmentIdentifier(job.scriptURL, newestWorker->scriptURL()) && job.registrationOptions.updateViaCache == registration->updateViaCache()) {
- resolveCurrentRegistrationJob(registration->data());
+ m_server.resolveRegistrationJob(firstJob(), registration->data());
+ finishCurrentJob();
return;
}
} else {
@@ -160,6 +155,7 @@
runUpdateJob(job);
}
+// https://w3c.github.io/ServiceWorker/#unregister-algorithm
void SWServerJobQueue::runUnregisterJob(const ServiceWorkerJobData& job)
{
// If the origin of job’s scope url is not job's client's origin, then:
@@ -172,7 +168,8 @@
// If registration is null, then:
if (!registration || registration->isUninstalling()) {
// Invoke Resolve Job Promise with job and false.
- resolveCurrentUnregistrationJob(false);
+ m_server.resolveUnregistrationJob(firstJob(), m_registrationKey, false);
+ finishCurrentJob();
return;
}
@@ -180,10 +177,11 @@
registration->setIsUninstalling(true);
// Invoke Resolve Job Promise with job and true.
- resolveCurrentUnregistrationJob(true);
+ m_server.resolveUnregistrationJob(firstJob(), m_registrationKey, true);
// Invoke Try Clear Registration with registration.
tryClearRegistration(*registration);
+ finishCurrentJob();
}
// https://w3c.github.io/ServiceWorker/#try-clear-registration-algorithm
@@ -203,6 +201,7 @@
m_server.removeRegistration(registration.key());
}
+// https://w3c.github.io/ServiceWorker/#update-algorithm
void SWServerJobQueue::runUpdateJob(const ServiceWorkerJobData& job)
{
auto* registration = m_server.getRegistration(m_registrationKey);
@@ -218,56 +217,24 @@
if (newestWorker && !equalIgnoringFragmentIdentifier(job.scriptURL, newestWorker->scriptURL()))
return rejectCurrentJob(ExceptionData { TypeError, ASCIILiteral("Cannot update a service worker with a requested script URL whose newest worker has a different script URL") });
- startScriptFetchForCurrentJob();
+ m_server.startScriptFetch(job);
}
void SWServerJobQueue::rejectCurrentJob(const ExceptionData& exceptionData)
{
- ASSERT(m_currentJob);
+ m_server.rejectJob(firstJob(), exceptionData);
- m_server.rejectJob(*m_currentJob, exceptionData);
-
finishCurrentJob();
}
-void SWServerJobQueue::resolveCurrentRegistrationJob(const ServiceWorkerRegistrationData& data)
-{
- ASSERT(m_currentJob);
- ASSERT(m_currentJob->type == ServiceWorkerJobType::Register);
-
- m_server.resolveRegistrationJob(*m_currentJob, data);
-
- finishCurrentJob();
-}
-
-void SWServerJobQueue::resolveCurrentUnregistrationJob(bool unregistrationResult)
-{
- ASSERT(m_currentJob);
- ASSERT(m_currentJob->type == ServiceWorkerJobType::Unregister);
-
- m_server.resolveUnregistrationJob(*m_currentJob, m_registrationKey, unregistrationResult);
-
- finishCurrentJob();
-}
-
-void SWServerJobQueue::startScriptFetchForCurrentJob()
-{
- ASSERT(m_currentJob);
-
- m_server.startScriptFetch(*m_currentJob);
-}
-
+// https://w3c.github.io/ServiceWorker/#finish-job
void SWServerJobQueue::finishCurrentJob()
{
- ASSERT(m_currentJob);
ASSERT(!m_jobTimer.isActive());
- m_currentJob = nullptr;
- if (m_jobQueue.isEmpty())
- return;
-
- ASSERT(!m_jobTimer.isActive());
- m_jobTimer.startOneShot(0_s);
+ m_jobQueue.removeFirst();
+ if (!m_jobQueue.isEmpty())
+ runNextJob();
}
} // namespace WebCore
Modified: trunk/Source/WebCore/workers/service/server/SWServerJobQueue.h (224340 => 224341)
--- trunk/Source/WebCore/workers/service/server/SWServerJobQueue.h 2017-11-02 17:24:02 UTC (rev 224340)
+++ trunk/Source/WebCore/workers/service/server/SWServerJobQueue.h 2017-11-02 17:38:57 UTC (rev 224341)
@@ -40,7 +40,13 @@
SWServerJobQueue(const SWServerRegistration&) = delete;
~SWServerJobQueue();
- void enqueueJob(const ServiceWorkerJobData&);
+ const ServiceWorkerJobData& firstJob() const { return m_jobQueue.first(); }
+ const ServiceWorkerJobData& lastJob() const { return m_jobQueue.last(); }
+ void enqueueJob(const ServiceWorkerJobData& jobData) { m_jobQueue.append(jobData); }
+ size_t size() const { return m_jobQueue.size(); }
+
+ void runNextJob();
+
void scriptFetchFinished(SWServer::Connection&, const ServiceWorkerFetchResult&);
void scriptContextFailedToStart(SWServer::Connection&, const String& workerID, const String& message);
void scriptContextStarted(SWServer::Connection&, uint64_t serviceWorkerIdentifier, const String& workerID);
@@ -47,11 +53,8 @@
private:
void jobTimerFired();
- void startNextJob();
+ void runNextJobSynchronously();
void rejectCurrentJob(const ExceptionData&);
- void resolveCurrentRegistrationJob(const ServiceWorkerRegistrationData&);
- void resolveCurrentUnregistrationJob(bool unregistrationResult);
- void startScriptFetchForCurrentJob();
void finishCurrentJob();
void runRegisterJob(const ServiceWorkerJobData&);
@@ -62,7 +65,6 @@
void clearRegistration(SWServerRegistration&);
Deque<ServiceWorkerJobData> m_jobQueue;
- std::unique_ptr<ServiceWorkerJobData> m_currentJob;
Timer m_jobTimer;
SWServer& m_server;