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

Side by Side Diff: content/browser/devtools/worker_devtools_manager.cc

Issue 11633035: DevTools: prepare workers for DevToolsManager::Attach(Detach)ClientHost removal. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Patch for landing Created 7 years, 12 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
« no previous file with comments | « content/browser/devtools/worker_devtools_manager.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/devtools/worker_devtools_manager.h" 5 #include "content/browser/devtools/worker_devtools_manager.h"
6 6
7 #include <list> 7 #include <list>
8 #include <map> 8 #include <map>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/lazy_instance.h" 11 #include "base/lazy_instance.h"
12 #include "content/browser/devtools/devtools_agent_host.h" 12 #include "content/browser/devtools/devtools_agent_host.h"
13 #include "content/browser/devtools/devtools_manager_impl.h" 13 #include "content/browser/devtools/devtools_manager_impl.h"
14 #include "content/browser/devtools/worker_devtools_message_filter.h" 14 #include "content/browser/devtools/worker_devtools_message_filter.h"
15 #include "content/browser/worker_host/worker_service_impl.h" 15 #include "content/browser/worker_host/worker_service_impl.h"
16 #include "content/common/devtools_messages.h" 16 #include "content/common/devtools_messages.h"
17 #include "content/public/browser/browser_thread.h" 17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/child_process_data.h" 18 #include "content/public/browser/child_process_data.h"
19 #include "content/public/browser/devtools_agent_host_registry.h" 19 #include "content/public/browser/devtools_agent_host_registry.h"
20 #include "content/public/common/process_type.h" 20 #include "content/public/common/process_type.h"
21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDevToolsAgent.h" 21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDevToolsAgent.h"
22 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCString.h " 22 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCString.h "
23 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" 23 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
24 24
25 using WebKit::WebDevToolsAgent;
26
25 namespace content { 27 namespace content {
26 28
27 // Called on the UI thread. 29 // Called on the UI thread.
28 // static 30 // static
29 DevToolsAgentHost* DevToolsAgentHostRegistry::GetDevToolsAgentHostForWorker( 31 DevToolsAgentHost* DevToolsAgentHostRegistry::GetDevToolsAgentHostForWorker(
30 int worker_process_id, 32 int worker_process_id,
31 int worker_route_id) { 33 int worker_route_id) {
32 return WorkerDevToolsManager::GetDevToolsAgentHostForWorker( 34 return WorkerDevToolsManager::GetDevToolsAgentHostForWorker(
33 worker_process_id, 35 worker_process_id,
34 worker_route_id); 36 worker_route_id);
35 } 37 }
36 38
37 namespace { 39 namespace {
38 40
41 static WorkerDevToolsManager::WorkerId g_null_id = std::make_pair(-1, -1);
42
39 typedef std::map<WorkerDevToolsManager::WorkerId, 43 typedef std::map<WorkerDevToolsManager::WorkerId,
40 WorkerDevToolsManager::WorkerDevToolsAgentHost*> AgentHosts; 44 WorkerDevToolsManager::WorkerDevToolsAgentHost*> AgentHosts;
41 typedef std::map<WorkerDevToolsManager::WorkerId,
42 int> OrphanHosts;
43 base::LazyInstance<AgentHosts>::Leaky g_agent_map = LAZY_INSTANCE_INITIALIZER; 45 base::LazyInstance<AgentHosts>::Leaky g_agent_map = LAZY_INSTANCE_INITIALIZER;
44 base::LazyInstance<OrphanHosts>::Leaky g_orphan_map = LAZY_INSTANCE_INITIALIZER; 46 base::LazyInstance<AgentHosts>::Leaky g_orphan_map = LAZY_INSTANCE_INITIALIZER;
45 47
46 } // namespace 48 } // namespace
47 49
48 struct WorkerDevToolsManager::TerminatedInspectedWorker { 50 struct WorkerDevToolsManager::TerminatedInspectedWorker {
49 TerminatedInspectedWorker(WorkerId id, const GURL& url, const string16& name) 51 TerminatedInspectedWorker(WorkerId id, const GURL& url, const string16& name)
50 : old_worker_id(id), 52 : old_worker_id(id),
51 worker_url(url), 53 worker_url(url),
52 worker_name(name) {} 54 worker_name(name) {}
53 WorkerId old_worker_id; 55 WorkerId old_worker_id;
54 GURL worker_url; 56 GURL worker_url;
55 string16 worker_name; 57 string16 worker_name;
56 }; 58 };
57 59
58 60
59 class WorkerDevToolsManager::WorkerDevToolsAgentHost 61 class WorkerDevToolsManager::WorkerDevToolsAgentHost
60 : public DevToolsAgentHost { 62 : public DevToolsAgentHost {
61 public: 63 public:
62 explicit WorkerDevToolsAgentHost(WorkerId worker_id) 64 explicit WorkerDevToolsAgentHost(WorkerId worker_id) {
63 : worker_id_(worker_id) { 65 SetWorkerId(worker_id, false);
66 }
67
68 void SetWorkerId(WorkerId worker_id, bool reattach) {
69 worker_id_ = worker_id;
64 g_agent_map.Get()[worker_id_] = this; 70 g_agent_map.Get()[worker_id_] = this;
71
65 BrowserThread::PostTask( 72 BrowserThread::PostTask(
66 BrowserThread::IO, 73 BrowserThread::IO,
67 FROM_HERE, 74 FROM_HERE,
68 base::Bind( 75 base::Bind(
69 &RegisterAgent, 76 &ConnectToWorker,
70 worker_id.first, 77 worker_id.first,
71 worker_id.second)); 78 worker_id.second));
79
80 if (reattach)
81 Reattach(state_);
72 } 82 }
73 83
74 void WorkerDestroyed() { 84 void ResetWorkerId() {
75 NotifyCloseListener(); 85 g_agent_map.Get().erase(worker_id_);
86 worker_id_ = g_null_id;
87 }
88
89 virtual void Detach() {
90 DevToolsAgentHost::Detach();
91 SelfDestruct();
92 }
93
94 void SaveAgentRuntimeState(const std::string& state) {
95 state_ = state;
96 }
97
98 void ConnectionFailed() {
99 // Depending on whether we are connected or not, we should disconnect and
100 // self-destruct.
101 if (NotifyCloseListener())
102 return; // Detach will delete this instance.
103 SelfDestruct();
104 }
105
106 void SelfDestruct() {
76 delete this; 107 delete this;
77 } 108 }
78 109
79 private: 110 private:
80 virtual ~WorkerDevToolsAgentHost() { 111 virtual ~WorkerDevToolsAgentHost() {
81 g_agent_map.Get().erase(worker_id_); 112 g_agent_map.Get().erase(worker_id_);
82 } 113 }
83 114
84 static void RegisterAgent( 115 static void ConnectToWorker(
85 int worker_process_id, 116 int worker_process_id,
86 int worker_route_id) { 117 int worker_route_id) {
87 WorkerDevToolsManager::GetInstance()->RegisterDevToolsAgentHostForWorker( 118 WorkerDevToolsManager::GetInstance()->ConnectDevToolsAgentHostToWorker(
88 worker_process_id, worker_route_id); 119 worker_process_id, worker_route_id);
89 } 120 }
90 121
91 static void ForwardToWorkerDevToolsAgent( 122 static void ForwardToWorkerDevToolsAgent(
92 int worker_process_id, 123 int worker_process_id,
93 int worker_route_id, 124 int worker_route_id,
94 IPC::Message* message) { 125 IPC::Message* message) {
95 WorkerDevToolsManager::GetInstance()->ForwardToWorkerDevToolsAgent( 126 WorkerDevToolsManager::GetInstance()->ForwardToWorkerDevToolsAgent(
96 worker_process_id, worker_route_id, *message); 127 worker_process_id, worker_route_id, *message);
97 } 128 }
98 129
99 // DevToolsAgentHost implementation. 130 // DevToolsAgentHost implementation.
100 virtual void SendMessageToAgent(IPC::Message* message) OVERRIDE { 131 virtual void SendMessageToAgent(IPC::Message* message) OVERRIDE {
132 if (worker_id_ == g_null_id) {
133 delete message;
134 return;
135 }
101 BrowserThread::PostTask( 136 BrowserThread::PostTask(
102 BrowserThread::IO, FROM_HERE, 137 BrowserThread::IO, FROM_HERE,
103 base::Bind( 138 base::Bind(
104 &WorkerDevToolsAgentHost::ForwardToWorkerDevToolsAgent, 139 &WorkerDevToolsAgentHost::ForwardToWorkerDevToolsAgent,
105 worker_id_.first, 140 worker_id_.first,
106 worker_id_.second, 141 worker_id_.second,
107 base::Owned(message))); 142 base::Owned(message)));
108 } 143 }
144
109 virtual void NotifyClientAttaching() OVERRIDE {} 145 virtual void NotifyClientAttaching() OVERRIDE {}
110 virtual void NotifyClientDetaching() OVERRIDE {} 146 virtual void NotifyClientDetaching() OVERRIDE {}
111 virtual int GetRenderProcessId() OVERRIDE { return -1; } 147 virtual int GetRenderProcessId() OVERRIDE { return -1; }
112 148
113 WorkerId worker_id_; 149 WorkerId worker_id_;
150 std::string state_;
114 151
115 DISALLOW_COPY_AND_ASSIGN(WorkerDevToolsAgentHost); 152 DISALLOW_COPY_AND_ASSIGN(WorkerDevToolsAgentHost);
116 }; 153 };
117 154
118 155
119 class WorkerDevToolsManager::DetachedClientHosts { 156 class WorkerDevToolsManager::DetachedClientHosts {
120 public: 157 public:
121 static void WorkerReloaded(WorkerId old_id, WorkerId new_id) { 158 static void WorkerReloaded(WorkerId old_id, WorkerId new_id) {
122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
123 if (ReattachClient(old_id, new_id)) 160 AgentHosts::iterator it = g_orphan_map.Get().find(old_id);
161 if (it != g_orphan_map.Get().end()) {
162 g_orphan_map.Get().erase(old_id);
163 it->second->SetWorkerId(new_id, true);
124 return; 164 return;
165 }
125 RemovePendingWorkerData(old_id); 166 RemovePendingWorkerData(old_id);
126 } 167 }
127 168
128 static void WorkerDestroyed(WorkerId id) { 169 static void WorkerDestroyed(WorkerId id) {
129 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 170 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
130 AgentHosts::iterator it = g_agent_map.Get().find(id); 171 AgentHosts::iterator it = g_agent_map.Get().find(id);
131 if (it == g_agent_map.Get().end()) { 172 if (it == g_agent_map.Get().end()) {
132 RemovePendingWorkerData(id); 173 RemovePendingWorkerData(id);
133 return; 174 return;
134 } 175 }
176
135 WorkerDevToolsAgentHost* agent = it->second; 177 WorkerDevToolsAgentHost* agent = it->second;
136 DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend( 178 DevToolsManagerImpl* devtools_manager = DevToolsManagerImpl::GetInstance();
137 agent, 179 DevToolsClientHost* client_host =
138 WebKit::WebDevToolsAgent::workerDisconnectedFromWorkerEvent().utf8()); 180 devtools_manager->GetDevToolsClientHostFor(agent);
139 int cookie = DevToolsManagerImpl::GetInstance()->DetachClientHost(agent); 181
140 agent->WorkerDestroyed(); 182 if (!client_host) {
141 if (cookie == -1) { 183 // Agent has no client hosts -> delete it.
142 RemovePendingWorkerData(id); 184 RemovePendingWorkerData(id);
185 agent->SelfDestruct();
143 return; 186 return;
144 } 187 }
145 g_orphan_map.Get()[id] = cookie; 188
189 // Client host is debugging this worker agent host.
190 devtools_manager->DispatchOnInspectorFrontend(
191 agent,
192 WebDevToolsAgent::workerDisconnectedFromWorkerEvent().utf8());
193 g_orphan_map.Get()[id] = agent;
194 agent->ResetWorkerId();
146 } 195 }
147 196
148 private: 197 private:
149 DetachedClientHosts() {} 198 DetachedClientHosts() {}
150 ~DetachedClientHosts() {} 199 ~DetachedClientHosts() {}
151 200
152 static bool ReattachClient(WorkerId old_id, WorkerId new_id) {
153 OrphanHosts::iterator it = g_orphan_map.Get().find(old_id);
154 if (it == g_orphan_map.Get().end())
155 return false;
156 DevToolsAgentHost* agent =
157 WorkerDevToolsManager::GetDevToolsAgentHostForWorker(
158 new_id.first,
159 new_id.second);
160 DevToolsManagerImpl::GetInstance()->AttachClientHost(
161 it->second,
162 agent);
163 g_orphan_map.Get().erase(it);
164 return true;
165 }
166
167 static void RemovePendingWorkerData(WorkerId id) { 201 static void RemovePendingWorkerData(WorkerId id) {
168 BrowserThread::PostTask( 202 BrowserThread::PostTask(
169 BrowserThread::IO, FROM_HERE, 203 BrowserThread::IO, FROM_HERE,
170 base::Bind(&RemoveInspectedWorkerDataOnIOThread, id)); 204 base::Bind(&RemoveInspectedWorkerDataOnIOThread, id));
171 } 205 }
172 206
173 static void RemoveInspectedWorkerDataOnIOThread(WorkerId id) { 207 static void RemoveInspectedWorkerDataOnIOThread(WorkerId id) {
174 WorkerDevToolsManager::GetInstance()->RemoveInspectedWorkerData(id); 208 WorkerDevToolsManager::GetInstance()->RemoveInspectedWorkerData(id);
175 } 209 }
176 }; 210 };
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 } 332 }
299 333
300 static WorkerProcessHost* FindWorkerProcess(int worker_process_id) { 334 static WorkerProcessHost* FindWorkerProcess(int worker_process_id) {
301 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { 335 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) {
302 if (iter.GetData().id == worker_process_id) 336 if (iter.GetData().id == worker_process_id)
303 return *iter; 337 return *iter;
304 } 338 }
305 return NULL; 339 return NULL;
306 } 340 }
307 341
308 void WorkerDevToolsManager::RegisterDevToolsAgentHostForWorker( 342 void WorkerDevToolsManager::ConnectDevToolsAgentHostToWorker(
309 int worker_process_id, 343 int worker_process_id,
310 int worker_route_id) { 344 int worker_route_id) {
311 if (WorkerProcessHost* process = FindWorkerProcess(worker_process_id)) { 345 if (WorkerProcessHost* process = FindWorkerProcess(worker_process_id)) {
312 const WorkerProcessHost::Instances& instances = process->instances(); 346 const WorkerProcessHost::Instances& instances = process->instances();
313 for (WorkerProcessHost::Instances::const_iterator i = instances.begin(); 347 for (WorkerProcessHost::Instances::const_iterator i = instances.begin();
314 i != instances.end(); ++i) { 348 i != instances.end(); ++i) {
315 if (i->worker_route_id() == worker_route_id) { 349 if (i->worker_route_id() == worker_route_id) {
316 DCHECK(FindInspectedWorker(worker_process_id, worker_route_id) == 350 DCHECK(FindInspectedWorker(worker_process_id, worker_route_id) ==
317 inspected_workers_.end()); 351 inspected_workers_.end());
318 inspected_workers_.push_back( 352 inspected_workers_.push_back(
319 InspectedWorker(process, worker_route_id, i->url(), i->name())); 353 InspectedWorker(process, worker_route_id, i->url(), i->name()));
320 return; 354 return;
321 } 355 }
322 } 356 }
323 } 357 }
324 NotifyWorkerDestroyedOnIOThread(worker_process_id, worker_route_id); 358 NotifyConnectionFailedOnIOThread(worker_process_id, worker_route_id);
325 } 359 }
326 360
327 void WorkerDevToolsManager::ForwardToDevToolsClient( 361 void WorkerDevToolsManager::ForwardToDevToolsClient(
328 int worker_process_id, 362 int worker_process_id,
329 int worker_route_id, 363 int worker_route_id,
330 const std::string& message) { 364 const std::string& message) {
331 if (FindInspectedWorker(worker_process_id, worker_route_id) == 365 if (FindInspectedWorker(worker_process_id, worker_route_id) ==
332 inspected_workers_.end()) { 366 inspected_workers_.end()) {
333 NOTREACHED(); 367 NOTREACHED();
334 return; 368 return;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 417
384 // static 418 // static
385 void WorkerDevToolsManager::SaveAgentRuntimeStateOnUIThread( 419 void WorkerDevToolsManager::SaveAgentRuntimeStateOnUIThread(
386 int worker_process_id, 420 int worker_process_id,
387 int worker_route_id, 421 int worker_route_id,
388 const std::string& state) { 422 const std::string& state) {
389 AgentHosts::iterator it = g_agent_map.Get().find(WorkerId(worker_process_id, 423 AgentHosts::iterator it = g_agent_map.Get().find(WorkerId(worker_process_id,
390 worker_route_id)); 424 worker_route_id));
391 if (it == g_agent_map.Get().end()) 425 if (it == g_agent_map.Get().end())
392 return; 426 return;
393 DevToolsManagerImpl::GetInstance()->SaveAgentRuntimeState(it->second, state); 427 it->second->SaveAgentRuntimeState(state);
394 } 428 }
395 429
396 // static 430 // static
397 void WorkerDevToolsManager::NotifyWorkerDestroyedOnIOThread( 431 void WorkerDevToolsManager::NotifyConnectionFailedOnIOThread(
398 int worker_process_id, 432 int worker_process_id,
399 int worker_route_id) { 433 int worker_route_id) {
400 BrowserThread::PostTask( 434 BrowserThread::PostTask(
401 BrowserThread::UI, FROM_HERE, 435 BrowserThread::UI, FROM_HERE,
402 base::Bind( 436 base::Bind(
403 &WorkerDevToolsManager::NotifyWorkerDestroyedOnUIThread, 437 &WorkerDevToolsManager::NotifyConnectionFailedOnUIThread,
404 worker_process_id, 438 worker_process_id,
405 worker_route_id)); 439 worker_route_id));
406 } 440 }
407 441
408 // static 442 // static
409 void WorkerDevToolsManager::NotifyWorkerDestroyedOnUIThread( 443 void WorkerDevToolsManager::NotifyConnectionFailedOnUIThread(
410 int worker_process_id, 444 int worker_process_id,
411 int worker_route_id) { 445 int worker_route_id) {
412 AgentHosts::iterator it = g_agent_map.Get().find(WorkerId(worker_process_id, 446 AgentHosts::iterator it = g_agent_map.Get().find(WorkerId(worker_process_id,
413 worker_route_id)); 447 worker_route_id));
414 if (it != g_agent_map.Get().end()) 448 if (it != g_agent_map.Get().end())
415 it->second->WorkerDestroyed(); 449 it->second->ConnectionFailed();
416 } 450 }
417 451
418 // static 452 // static
419 void WorkerDevToolsManager::SendResumeToWorker(const WorkerId& id) { 453 void WorkerDevToolsManager::SendResumeToWorker(const WorkerId& id) {
420 if (WorkerProcessHost* process = FindWorkerProcess(id.first)) 454 if (WorkerProcessHost* process = FindWorkerProcess(id.first))
421 process->Send(new DevToolsAgentMsg_ResumeWorkerContext(id.second)); 455 process->Send(new DevToolsAgentMsg_ResumeWorkerContext(id.second));
422 } 456 }
423 457
424 } // namespace content 458 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/devtools/worker_devtools_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698