1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "extensions/renderer/worker_script_context_set.h"
9 #include "extensions/renderer/script_context.h"
11 namespace extensions
{
13 using ContextVector
= ScopedVector
<ScriptContext
>;
17 // Returns an iterator to the ScriptContext associated with |v8_context| from
18 // |contexts|, or |contexts|->end() if not found.
19 ContextVector::iterator
FindContext(ContextVector
* contexts
,
20 v8::Local
<v8::Context
> v8_context
) {
21 auto context_matches
= [&v8_context
](ScriptContext
* context
) {
22 v8::HandleScope
handle_scope(context
->isolate());
23 v8::Context::Scope
context_scope(context
->v8_context());
24 return context
->v8_context() == v8_context
;
26 return std::find_if(contexts
->begin(), contexts
->end(), context_matches
);
31 WorkerScriptContextSet::WorkerScriptContextSet() {}
33 WorkerScriptContextSet::~WorkerScriptContextSet() {}
35 void WorkerScriptContextSet::Insert(scoped_ptr
<ScriptContext
> context
) {
36 DCHECK_GT(content::WorkerThread::GetCurrentId(), 0)
37 << "Must be called on a worker thread";
38 ContextVector
* contexts
= contexts_tls_
.Get();
40 // First context added for this thread. Create a new set, then wait for
41 // this thread's shutdown.
42 contexts
= new ContextVector();
43 contexts_tls_
.Set(contexts
);
44 content::WorkerThread::AddObserver(this);
46 CHECK(FindContext(contexts
, context
->v8_context()) == contexts
->end())
47 << "Worker for " << context
->url() << " is already in this set";
48 contexts
->push_back(context
.Pass());
51 void WorkerScriptContextSet::Remove(v8::Local
<v8::Context
> v8_context
,
53 DCHECK_GT(content::WorkerThread::GetCurrentId(), 0)
54 << "Must be called on a worker thread";
55 ContextVector
* contexts
= contexts_tls_
.Get();
57 // Thread has already been torn down, and |v8_context| removed. I'm not
58 // sure this can actually happen (depends on in what order blink fires
59 // events), but SW lifetime has bitten us before, so be cautious.
62 auto context_it
= FindContext(contexts
, v8_context
);
63 CHECK(context_it
!= contexts
->end()) << "Worker for " << url
64 << " is not in this set";
65 ScriptContext
* context
= *context_it
;
66 DCHECK_EQ(url
, context
->url());
67 context
->Invalidate();
68 contexts
->erase(context_it
);
71 void WorkerScriptContextSet::WillStopCurrentWorkerThread() {
72 content::WorkerThread::RemoveObserver(this);
73 ContextVector
* contexts
= contexts_tls_
.Get();
75 for (ScriptContext
* context
: *contexts
)
76 context
->Invalidate();
77 contexts_tls_
.Set(nullptr);
81 } // namespace extensions