| 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) {
|
|
|