Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 base { | |
| 14 // Destroying ServiceWorkerProcessManagers only on the UI thread allows the | |
| 15 // member WeakPtr to safely guard the object's lifetime when used on that | |
| 16 // thread. | |
| 17 void DefaultDeleter<content::ServiceWorkerProcessManager>::operator()( | |
| 18 content::ServiceWorkerProcessManager* ptr) const { | |
| 19 content::BrowserThread::DeleteSoon( | |
| 20 content::BrowserThread::UI, FROM_HERE, ptr); | |
| 21 } | |
| 22 } // namespace base | |
| 23 | |
| 24 namespace content { | |
| 25 | |
| 26 ServiceWorkerProcessManager::ServiceWorkerProcessManager( | |
| 27 ServiceWorkerContextWrapper* context_wrapper, | |
| 28 const base::Callback<bool(int)>& increment_for_test, | |
| 29 const base::Callback<bool(int)>& decrement_for_test) | |
| 30 : context_wrapper_(context_wrapper), | |
| 31 increment_for_test_(increment_for_test), | |
| 32 decrement_for_test_(decrement_for_test), | |
| 33 weak_this_factory_(this), | |
| 34 weak_this_(weak_this_factory_.GetWeakPtr()) { | |
| 35 } | |
| 36 | |
| 37 ServiceWorkerProcessManager::~ServiceWorkerProcessManager() { | |
| 38 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 39 } | |
| 40 | |
| 41 void ServiceWorkerProcessManager::AllocateWorkerProcess( | |
| 42 const std::vector<int>& process_ids, | |
| 43 const GURL& script_url, | |
| 44 const base::Callback<void(ServiceWorkerStatusCode, int process_id)>& | |
| 45 callback) const { | |
| 46 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | |
| 47 BrowserThread::PostTask( | |
| 48 BrowserThread::UI, | |
| 49 FROM_HERE, | |
| 50 base::Bind(&ServiceWorkerProcessManager::AllocateWorkerProcess, | |
| 51 weak_this_, | |
|
kinuko
2014/04/28 06:58:16
nit: This doesn't seem necessary given that it's p
Jeffrey Yasskin
2014/04/28 20:47:40
Yeah, I believe we don't need the WeakPtrFactory a
| |
| 52 process_ids, | |
| 53 script_url, | |
| 54 callback)); | |
| 55 return; | |
| 56 } | |
| 57 | |
| 58 for (std::vector<int>::const_iterator it = process_ids.begin(); | |
| 59 it != process_ids.end(); | |
| 60 ++it) { | |
| 61 if (IncrementWorkerRefcountByPid(*it)) { | |
| 62 BrowserThread::PostTask(BrowserThread::IO, | |
| 63 FROM_HERE, | |
| 64 base::Bind(callback, SERVICE_WORKER_OK, *it)); | |
| 65 return; | |
| 66 } | |
| 67 } | |
| 68 | |
| 69 if (!context_wrapper_->browser_context_) { | |
| 70 // Shutdown has started. | |
|
kinuko
2014/04/28 06:58:16
Should this be checked before we loop over process
Jeffrey Yasskin
2014/04/28 20:47:40
No, if we do that, a lot of the unittests would ne
| |
| 71 BrowserThread::PostTask( | |
| 72 BrowserThread::IO, | |
| 73 FROM_HERE, | |
| 74 base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED, -1)); | |
| 75 } | |
| 76 // No existing processes available; start a new one. | |
| 77 scoped_refptr<SiteInstance> site_instance = SiteInstance::CreateForURL( | |
| 78 context_wrapper_->browser_context_, script_url); | |
| 79 RenderProcessHost* rph = site_instance->GetProcess(); | |
| 80 // This Init() call posts a task to the IO thread that adds the RPH's | |
| 81 // ServiceWorkerDispatcherHost to the | |
| 82 // EmbeddedWorkerRegistry::process_sender_map_. | |
| 83 if (!rph->Init()) { | |
| 84 LOG(ERROR) << "Couldn't start a new process!"; | |
| 85 BrowserThread::PostTask( | |
| 86 BrowserThread::IO, | |
| 87 FROM_HERE, | |
| 88 base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED, -1)); | |
| 89 return; | |
| 90 } | |
| 91 | |
| 92 static_cast<RenderProcessHostImpl*>(rph)->IncrementWorkerRefCount(); | |
| 93 BrowserThread::PostTask( | |
| 94 BrowserThread::IO, | |
| 95 FROM_HERE, | |
| 96 base::Bind(callback, SERVICE_WORKER_OK, rph->GetID())); | |
| 97 } | |
| 98 | |
| 99 void ServiceWorkerProcessManager::ReleaseWorkerProcess(int process_id) { | |
| 100 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | |
| 101 BrowserThread::PostTask( | |
| 102 BrowserThread::UI, | |
| 103 FROM_HERE, | |
| 104 base::Bind(&ServiceWorkerProcessManager::ReleaseWorkerProcess, | |
| 105 weak_this_, | |
| 106 process_id)); | |
| 107 return; | |
| 108 } | |
| 109 if (!DecrementWorkerRefcountByPid(process_id)) { | |
| 110 DCHECK(false) << "DecrementWorkerRef(" << process_id | |
| 111 << ") doesn't match a previous IncrementWorkerRef"; | |
| 112 } | |
| 113 } | |
| 114 | |
| 115 bool ServiceWorkerProcessManager::IncrementWorkerRefcountByPid( | |
| 116 int process_id) const { | |
| 117 if (!increment_for_test_.is_null()) | |
| 118 return increment_for_test_.Run(process_id); | |
| 119 | |
| 120 RenderProcessHost* rph = RenderProcessHost::FromID(process_id); | |
| 121 if (rph && !rph->FastShutdownStarted()) | |
| 122 static_cast<RenderProcessHostImpl*>(rph)->IncrementWorkerRefCount(); | |
| 123 | |
| 124 return rph != NULL; | |
|
kinuko
2014/04/28 06:58:16
Since we only increment worker-ref when line 121 i
Jeffrey Yasskin
2014/04/28 20:47:40
Yep, I forgot to update enough of this when I adde
| |
| 125 } | |
| 126 | |
| 127 bool ServiceWorkerProcessManager::DecrementWorkerRefcountByPid( | |
| 128 int process_id) const { | |
| 129 if (!decrement_for_test_.is_null()) | |
| 130 return decrement_for_test_.Run(process_id); | |
| 131 | |
| 132 RenderProcessHost* rph = RenderProcessHost::FromID(process_id); | |
| 133 if (rph) | |
| 134 static_cast<RenderProcessHostImpl*>(rph)->DecrementWorkerRefCount(); | |
| 135 | |
| 136 return rph != NULL; | |
| 137 } | |
| 138 | |
| 139 } // namespace content | |
| OLD | NEW |