Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(498)

Side by Side Diff: content/browser/service_worker/service_worker_process_manager.cc

Issue 238043002: Teach EmbeddedWorkerInstance to create a process when it needs one. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Handle 2 places where context_ could be NULL. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 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.
4
5 #include "content/browser/service_worker/service_worker_process_manager.h"
6
7 #include "content/browser/renderer_host/render_process_host_impl.h"
8 #include "content/browser/service_worker/service_worker_context_wrapper.h"
9 #include "content/public/browser/browser_thread.h"
10 #include "content/public/browser/site_instance.h"
11 #include "url/gurl.h"
12
13 namespace content {
14
15 ServiceWorkerProcessManager::ServiceWorkerProcessManager(
16 ServiceWorkerContextWrapper* context_wrapper)
17 : context_wrapper_(context_wrapper),
18 weak_this_factory_(this),
19 weak_this_(weak_this_factory_.GetWeakPtr()) {
20 }
21
22 ServiceWorkerProcessManager::~ServiceWorkerProcessManager() {
23 DCHECK_CURRENTLY_ON(BrowserThread::UI);
24 }
25
26 void ServiceWorkerProcessManager::AllocateWorkerProcess(
27 const std::vector<int>& process_ids,
28 const GURL& script_url,
29 const base::Callback<void(ServiceWorkerStatusCode, int process_id)>&
30 callback) const {
31 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
32 BrowserThread::PostTask(
33 BrowserThread::UI,
34 FROM_HERE,
35 base::Bind(&ServiceWorkerProcessManager::AllocateWorkerProcess,
36 weak_this_,
37 process_ids,
38 script_url,
39 callback));
40 return;
41 }
42
43 for (std::vector<int>::const_iterator it = process_ids.begin();
44 it != process_ids.end();
45 ++it) {
46 if (IncrementWorkerRefcountByPid(*it)) {
47 BrowserThread::PostTask(BrowserThread::IO,
48 FROM_HERE,
49 base::Bind(callback, SERVICE_WORKER_OK, *it));
50 return;
51 }
52 }
53
54 if (!context_wrapper_->browser_context_) {
55 // Shutdown has started.
56 BrowserThread::PostTask(
57 BrowserThread::IO,
58 FROM_HERE,
59 base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED, -1));
60 return;
61 }
62 // No existing processes available; start a new one.
63 scoped_refptr<SiteInstance> site_instance = SiteInstance::CreateForURL(
64 context_wrapper_->browser_context_, script_url);
65 RenderProcessHost* rph = site_instance->GetProcess();
66 // This Init() call posts a task to the IO thread that adds the RPH's
67 // ServiceWorkerDispatcherHost to the
68 // EmbeddedWorkerRegistry::process_sender_map_.
69 if (!rph->Init()) {
70 LOG(ERROR) << "Couldn't start a new process!";
71 BrowserThread::PostTask(
72 BrowserThread::IO,
73 FROM_HERE,
74 base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED, -1));
75 return;
76 }
77
78 static_cast<RenderProcessHostImpl*>(rph)->IncrementWorkerRefCount();
79 BrowserThread::PostTask(
80 BrowserThread::IO,
81 FROM_HERE,
82 base::Bind(callback, SERVICE_WORKER_OK, rph->GetID()));
83 }
84
85 void ServiceWorkerProcessManager::ReleaseWorkerProcess(int process_id) {
86 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
87 BrowserThread::PostTask(
88 BrowserThread::UI,
89 FROM_HERE,
90 base::Bind(&ServiceWorkerProcessManager::ReleaseWorkerProcess,
91 weak_this_,
92 process_id));
93 return;
94 }
95 if (!DecrementWorkerRefcountByPid(process_id)) {
96 DCHECK(false) << "DecrementWorkerRef(" << process_id
97 << ") doesn't match a previous IncrementWorkerRef";
98 }
99 }
100
101 void ServiceWorkerProcessManager::SetProcessRefcountOpsForTest(
102 const base::Callback<bool(int)>& increment_for_test,
103 const base::Callback<bool(int)>& decrement_for_test) {
104 increment_for_test_ = increment_for_test;
105 decrement_for_test_ = decrement_for_test;
106 }
107
108 bool ServiceWorkerProcessManager::IncrementWorkerRefcountByPid(
109 int process_id) const {
110 if (!increment_for_test_.is_null())
111 return increment_for_test_.Run(process_id);
112
113 RenderProcessHost* rph = RenderProcessHost::FromID(process_id);
114 if (rph && !rph->FastShutdownStarted()) {
115 static_cast<RenderProcessHostImpl*>(rph)->IncrementWorkerRefCount();
116 return true;
117 }
118
119 return false;
120 }
121
122 bool ServiceWorkerProcessManager::DecrementWorkerRefcountByPid(
123 int process_id) const {
124 if (!decrement_for_test_.is_null())
125 return decrement_for_test_.Run(process_id);
126
127 RenderProcessHost* rph = RenderProcessHost::FromID(process_id);
128 if (rph)
129 static_cast<RenderProcessHostImpl*>(rph)->DecrementWorkerRefCount();
130
131 return rph != NULL;
132 }
133
134 } // namespace content
135
136 namespace base {
137 // Destroying ServiceWorkerProcessManagers only on the UI thread allows the
138 // member WeakPtr to safely guard the object's lifetime when used on that
139 // thread.
140 void DefaultDeleter<content::ServiceWorkerProcessManager>::operator()(
141 content::ServiceWorkerProcessManager* ptr) const {
142 content::BrowserThread::DeleteSoon(
143 content::BrowserThread::UI, FROM_HERE, ptr);
144 }
145 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698