Index: extensions/renderer/dispatcher.cc |
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc |
index 1203e6f30964ce7a3fa2503579186a2b53a04710..34324e2be1bf10a27c375337e720fd03c5a85029 100644 |
--- a/extensions/renderer/dispatcher.cc |
+++ b/extensions/renderer/dispatcher.cc |
@@ -197,41 +197,21 @@ |
ServiceWorkerScriptContextSet() {} |
~ServiceWorkerScriptContextSet() {} |
- void Insert(scoped_ptr<ScriptContext> context) { |
+ void Insert(const GURL& url, scoped_ptr<ScriptContext> context) { |
base::AutoLock lock(lock_); |
- CHECK(FindScriptContext(context->v8_context()) == contexts_.end()); |
- contexts_.push_back(context.Pass()); |
- } |
- |
- void Remove(v8::Local<v8::Context> v8_context) { |
+ CHECK(script_contexts_.find(url) == script_contexts_.end()); |
+ script_contexts_.set(url, context.Pass()); |
+ } |
+ |
+ void Remove(const GURL& url) { |
base::AutoLock lock(lock_); |
- ScriptContextList::iterator context_it = FindScriptContext(v8_context); |
- // TODO(kalman): It would be good to CHECK(context_it != contexts_.end()) |
- // here, but service workers can be started before the extension has been |
- // installed. See the length comment explaining why this happens, and |
- // how to solve it, in DidInitializeServiceWorkerContextOnWorkerThread. |
- // This does need to be fixed eventually, but for now, at least don't crash. |
- if (context_it == contexts_.end()) |
- return; |
- (*context_it)->Invalidate(); |
- contexts_.erase(context_it); |
+ scoped_ptr<ScriptContext> context = script_contexts_.take_and_erase(url); |
+ CHECK(context); |
+ context->Invalidate(); |
} |
private: |
- using ScriptContextList = ScopedVector<ScriptContext>; |
- |
- // Returns an iterator to the ScriptContext associated with |v8_context|, or |
- // contexts_.end() if not found. |
- ScriptContextList::iterator FindScriptContext( |
- v8::Local<v8::Context> v8_context) { |
- for (auto it = contexts_.begin(); it != contexts_.end(); ++it) { |
- if ((*it)->v8_context() == v8_context) |
- return it; |
- } |
- return contexts_.end(); |
- } |
- |
- ScriptContextList contexts_; |
+ base::ScopedPtrMap<GURL, scoped_ptr<ScriptContext>> script_contexts_; |
mutable base::Lock lock_; |
@@ -403,35 +383,15 @@ |
const Extension* extension = |
RendererExtensionRegistry::Get()->GetExtensionOrAppByURL(url); |
- if (!extension) { |
- // TODO(kalman): This is no good. Instead we need to either: |
- // |
- // - Hold onto the v8::Context and create the ScriptContext and install |
- // our bindings when this extension is loaded. |
- // - Deal with there being an extension ID (url.host()) but no |
- // extension associated with it, then document that getBackgroundClient |
- // may fail if the extension hasn't loaded yet. |
- // |
- // The former is safer, but is unfriendly to caching (e.g. session restore). |
- // It seems to contradict the service worker idiom. |
- // |
- // The latter is friendly to caching, but running extension code without an |
- // installed extension makes me nervous, and means that we won't be able to |
- // expose arbitrary (i.e. capability-checked) extension APIs to service |
- // workers. We will probably need to relax some assertions - we just need |
- // to find them. |
- // |
- // Perhaps this could be solved with our own event on the service worker |
- // saying that an extension is ready, and documenting that extension APIs |
- // won't work before that event has fired? |
+ if (!extension) |
return; |
- } |
ScriptContext* context = new ScriptContext( |
v8_context, nullptr, extension, Feature::SERVICE_WORKER_CONTEXT, |
extension, Feature::SERVICE_WORKER_CONTEXT); |
- g_service_worker_script_context_set.Get().Insert(make_scoped_ptr(context)); |
+ g_service_worker_script_context_set.Get().Insert(url, |
+ make_scoped_ptr(context)); |
v8::Isolate* isolate = context->isolate(); |
@@ -478,10 +438,9 @@ |
// static |
void Dispatcher::WillDestroyServiceWorkerContextOnWorkerThread( |
- v8::Local<v8::Context> v8_context, |
const GURL& url) { |
- if (url.SchemeIs(kExtensionScheme)) |
- g_service_worker_script_context_set.Get().Remove(v8_context); |
+ if (RendererExtensionRegistry::Get()->GetExtensionOrAppByURL(url)) |
+ g_service_worker_script_context_set.Get().Remove(url); |
} |
void Dispatcher::DidCreateDocumentElement(blink::WebLocalFrame* frame) { |