Commit 21258199 authored by Kenichi Ishibashi's avatar Kenichi Ishibashi Committed by Commit Bot

worker: Move pausing top-level classic script execution logic to WorkerGlobalScope

This CL moves logic to top-level script execution from
ServiceWorkerGlobalScope to WorkerGlobalScope so that we can use the same logic
among other WorkerGlobalScopes. We will use this functionality to avoid a race
condition which could happen when off-the-main-thread shared worker script fetch
is enabled.

Change-Id: Ib34373fe7864189da5ba4c00d19db2c027ce36cc
Bug: 945673
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1616863
Auto-Submit: Kenichi Ishibashi <bashi@chromium.org>
Commit-Queue: Hiroki Nakagawa <nhiroki@chromium.org>
Reviewed-by: default avatarHiroshige Hayashizaki <hiroshige@chromium.org>
Reviewed-by: default avatarHiroki Nakagawa <nhiroki@chromium.org>
Cr-Commit-Position: refs/heads/master@{#662039}
parent 5a3bf5a8
...@@ -98,6 +98,8 @@ DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope( ...@@ -98,6 +98,8 @@ DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope(
base::TimeTicks time_origin, base::TimeTicks time_origin,
std::unique_ptr<Vector<String>> outside_origin_trial_tokens) std::unique_ptr<Vector<String>> outside_origin_trial_tokens)
: WorkerGlobalScope(std::move(creation_params), thread, time_origin) { : WorkerGlobalScope(std::move(creation_params), thread, time_origin) {
// Dedicated workers don't need to pause after script fetch.
ReadyToRunClassicScript();
// Inherit the outside's origin trial tokens. // Inherit the outside's origin trial tokens.
OriginTrialContext::AddTokens(this, outside_origin_trial_tokens.get()); OriginTrialContext::AddTokens(this, outside_origin_trial_tokens.get());
} }
......
...@@ -26,7 +26,9 @@ class ThreadPoolWorkerGlobalScope final : public WorkerGlobalScope { ...@@ -26,7 +26,9 @@ class ThreadPoolWorkerGlobalScope final : public WorkerGlobalScope {
WorkerThread* thread) WorkerThread* thread)
: WorkerGlobalScope(std::move(creation_params), : WorkerGlobalScope(std::move(creation_params),
thread, thread,
CurrentTimeTicks()) {} CurrentTimeTicks()) {
ReadyToRunClassicScript();
}
~ThreadPoolWorkerGlobalScope() override = default; ~ThreadPoolWorkerGlobalScope() override = default;
......
...@@ -90,7 +90,10 @@ SharedWorkerGlobalScope::SharedWorkerGlobalScope( ...@@ -90,7 +90,10 @@ SharedWorkerGlobalScope::SharedWorkerGlobalScope(
std::unique_ptr<GlobalScopeCreationParams> creation_params, std::unique_ptr<GlobalScopeCreationParams> creation_params,
SharedWorkerThread* thread, SharedWorkerThread* thread,
base::TimeTicks time_origin) base::TimeTicks time_origin)
: WorkerGlobalScope(std::move(creation_params), thread, time_origin) {} : WorkerGlobalScope(std::move(creation_params), thread, time_origin) {
// TODO(bashi): Call this after appcache host is set.
ReadyToRunClassicScript();
}
SharedWorkerGlobalScope::~SharedWorkerGlobalScope() = default; SharedWorkerGlobalScope::~SharedWorkerGlobalScope() = default;
......
...@@ -390,11 +390,28 @@ void WorkerGlobalScope::ReceiveMessage(BlinkTransferableMessage message) { ...@@ -390,11 +390,28 @@ void WorkerGlobalScope::ReceiveMessage(BlinkTransferableMessage message) {
debugger->ExternalAsyncTaskFinished(message.sender_stack_trace_id); debugger->ExternalAsyncTaskFinished(message.sender_stack_trace_id);
} }
void WorkerGlobalScope::ReadyToRunClassicScript() {
DCHECK_EQ(ScriptEvalState::kPauseAfterFetch, script_eval_state_);
script_eval_state_ = ScriptEvalState::kReadyToEvaluate;
if (evaluate_script_)
std::move(evaluate_script_).Run();
}
void WorkerGlobalScope::EvaluateClassicScriptInternal( void WorkerGlobalScope::EvaluateClassicScriptInternal(
const KURL& script_url, const KURL& script_url,
String source_code, String source_code,
std::unique_ptr<Vector<uint8_t>> cached_meta_data) { std::unique_ptr<Vector<uint8_t>> cached_meta_data) {
DCHECK(IsContextThread()); DCHECK(IsContextThread());
DCHECK_NE(ScriptEvalState::kEvaluated, script_eval_state_);
if (script_eval_state_ == ScriptEvalState::kPauseAfterFetch) {
evaluate_script_ =
WTF::Bind(&WorkerGlobalScope::EvaluateClassicScriptInternal,
WrapWeakPersistent(this), script_url, std::move(source_code),
std::move(cached_meta_data));
return;
}
SingleCachedMetadataHandler* handler = SingleCachedMetadataHandler* handler =
CreateWorkerScriptCachedMetadataHandler(script_url, CreateWorkerScriptCachedMetadataHandler(script_url,
std::move(cached_meta_data)); std::move(cached_meta_data));
...@@ -408,6 +425,7 @@ void WorkerGlobalScope::EvaluateClassicScriptInternal( ...@@ -408,6 +425,7 @@ void WorkerGlobalScope::EvaluateClassicScriptInternal(
SanitizeScriptErrors::kDoNotSanitize, nullptr /* error_event */, SanitizeScriptErrors::kDoNotSanitize, nullptr /* error_event */,
GetV8CacheOptions()); GetV8CacheOptions());
ReportingProxy().DidEvaluateClassicScript(success); ReportingProxy().DidEvaluateClassicScript(success);
script_eval_state_ = ScriptEvalState::kEvaluated;
} }
WorkerGlobalScope::WorkerGlobalScope( WorkerGlobalScope::WorkerGlobalScope(
...@@ -435,7 +453,8 @@ WorkerGlobalScope::WorkerGlobalScope( ...@@ -435,7 +453,8 @@ WorkerGlobalScope::WorkerGlobalScope(
creation_params->begin_frame_provider_params)), creation_params->begin_frame_provider_params)),
agent_cluster_id_(creation_params->agent_cluster_id.is_empty() agent_cluster_id_(creation_params->agent_cluster_id.is_empty()
? base::UnguessableToken::Create() ? base::UnguessableToken::Create()
: creation_params->agent_cluster_id) { : creation_params->agent_cluster_id),
script_eval_state_(ScriptEvalState::kPauseAfterFetch) {
InstanceCounters::IncrementCounter( InstanceCounters::IncrementCounter(
InstanceCounters::kWorkerGlobalScopeCounter); InstanceCounters::kWorkerGlobalScopeCounter);
scoped_refptr<SecurityOrigin> security_origin = scoped_refptr<SecurityOrigin> security_origin =
......
...@@ -209,8 +209,13 @@ class CORE_EXPORT WorkerGlobalScope ...@@ -209,8 +209,13 @@ class CORE_EXPORT WorkerGlobalScope
void ExceptionThrown(ErrorEvent*) override; void ExceptionThrown(ErrorEvent*) override;
void RemoveURLFromMemoryCache(const KURL&) final; void RemoveURLFromMemoryCache(const KURL&) final;
// Notifies that the top-level classic script is ready to evaluate.
// Worker top-level script is evaluated after it is fetched and
// ReadyToRunClassicScript() is called.
void ReadyToRunClassicScript();
// Evaluates the given top-level classic script. // Evaluates the given top-level classic script.
virtual void EvaluateClassicScriptInternal( void EvaluateClassicScriptInternal(
const KURL& script_url, const KURL& script_url,
String source_code, String source_code,
std::unique_ptr<Vector<uint8_t>> cached_meta_data); std::unique_ptr<Vector<uint8_t>> cached_meta_data);
...@@ -260,6 +265,21 @@ class CORE_EXPORT WorkerGlobalScope ...@@ -260,6 +265,21 @@ class CORE_EXPORT WorkerGlobalScope
const base::UnguessableToken agent_cluster_id_; const base::UnguessableToken agent_cluster_id_;
// State transition about worker-toplevel script evaluation.
enum class ScriptEvalState {
// Initial state: ReadyToRunClassicScript() is not yet called.
// Worker top-level script fetch might or might not completed, and even when
// the fetch completes in this state, script evaluation will be deferred to
// when ReadyToRunClassicScript() is called later.
kPauseAfterFetch,
// ReadyToRunClassicScript() is already called.
kReadyToEvaluate,
// The worker top-level script is evaluated.
kEvaluated,
};
ScriptEvalState script_eval_state_;
base::OnceClosure evaluate_script_;
HttpsState https_state_; HttpsState https_state_;
}; };
......
...@@ -49,7 +49,9 @@ class FakeWorkerGlobalScope : public WorkerGlobalScope { ...@@ -49,7 +49,9 @@ class FakeWorkerGlobalScope : public WorkerGlobalScope {
WorkerThread* thread) WorkerThread* thread)
: WorkerGlobalScope(std::move(creation_params), : WorkerGlobalScope(std::move(creation_params),
thread, thread,
CurrentTimeTicks()) {} CurrentTimeTicks()) {
ReadyToRunClassicScript();
}
~FakeWorkerGlobalScope() override = default; ~FakeWorkerGlobalScope() override = default;
......
...@@ -162,10 +162,7 @@ ServiceWorkerGlobalScope::ServiceWorkerGlobalScope( ...@@ -162,10 +162,7 @@ ServiceWorkerGlobalScope::ServiceWorkerGlobalScope(
ServiceWorkerGlobalScope::~ServiceWorkerGlobalScope() = default; ServiceWorkerGlobalScope::~ServiceWorkerGlobalScope() = default;
void ServiceWorkerGlobalScope::ReadyToEvaluateScript() { void ServiceWorkerGlobalScope::ReadyToEvaluateScript() {
DCHECK(!evaluate_script_ready_); ReadyToRunClassicScript();
evaluate_script_ready_ = true;
if (evaluate_script_)
std::move(evaluate_script_).Run();
} }
bool ServiceWorkerGlobalScope::ShouldInstallV8Extensions() const { bool ServiceWorkerGlobalScope::ShouldInstallV8Extensions() const {
...@@ -584,26 +581,6 @@ bool ServiceWorkerGlobalScope::AddEventListenerInternal( ...@@ -584,26 +581,6 @@ bool ServiceWorkerGlobalScope::AddEventListenerInternal(
options); options);
} }
void ServiceWorkerGlobalScope::EvaluateClassicScriptInternal(
const KURL& script_url,
String source_code,
std::unique_ptr<Vector<uint8_t>> cached_meta_data) {
DCHECK(IsContextThread());
// TODO(nhiroki): Move this mechanism to
// WorkerGlobalScope::EvaluateClassicScriptInternal().
if (!evaluate_script_ready_) {
evaluate_script_ =
WTF::Bind(&ServiceWorkerGlobalScope::EvaluateClassicScriptInternal,
WrapWeakPersistent(this), script_url, std::move(source_code),
std::move(cached_meta_data));
return;
}
WorkerGlobalScope::EvaluateClassicScriptInternal(script_url, source_code,
std::move(cached_meta_data));
}
const AtomicString& ServiceWorkerGlobalScope::InterfaceName() const { const AtomicString& ServiceWorkerGlobalScope::InterfaceName() const {
return event_target_names::kServiceWorkerGlobalScope; return event_target_names::kServiceWorkerGlobalScope;
} }
......
...@@ -185,12 +185,6 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final : public WorkerGlobalScope { ...@@ -185,12 +185,6 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final : public WorkerGlobalScope {
EventListener*, EventListener*,
const AddEventListenerOptionsResolved*) override; const AddEventListenerOptionsResolved*) override;
// WorkerGlobalScope
void EvaluateClassicScriptInternal(
const KURL& script_url,
String source_code,
std::unique_ptr<Vector<uint8_t>> cached_meta_data) override;
private: private:
void importScripts(const HeapVector<StringOrTrustedScriptURL>& urls, void importScripts(const HeapVector<StringOrTrustedScriptURL>& urls,
ExceptionState&) override; ExceptionState&) override;
...@@ -236,9 +230,6 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final : public WorkerGlobalScope { ...@@ -236,9 +230,6 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final : public WorkerGlobalScope {
uint64_t cache_storage_installed_script_total_size_ = 0; uint64_t cache_storage_installed_script_total_size_ = 0;
uint64_t cache_storage_installed_script_metadata_total_size_ = 0; uint64_t cache_storage_installed_script_metadata_total_size_ = 0;
bool evaluate_script_ready_ = false;
base::OnceClosure evaluate_script_;
// May be provided in the constructor as an optimization so InterfaceProvider // May be provided in the constructor as an optimization so InterfaceProvider
// doesn't need to be used. Taken at the initial call to // doesn't need to be used. Taken at the initial call to
// ServiceWorkerGlobalScope#caches. // ServiceWorkerGlobalScope#caches.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment