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

Side by Side Diff: content/common/gpu/client/gpu_channel_host.cc

Issue 11886005: Fix GpuChannelHost destruction races. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: stupid ios Created 7 years, 11 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/common/gpu/client/gpu_channel_host.h" 5 #include "content/common/gpu/client/gpu_channel_host.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/message_loop_proxy.h" 10 #include "base/message_loop_proxy.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 channel_.reset(new IPC::SyncChannel( 45 channel_.reset(new IPC::SyncChannel(
46 channel_handle, IPC::Channel::MODE_CLIENT, NULL, 46 channel_handle, IPC::Channel::MODE_CLIENT, NULL,
47 io_loop, true, 47 io_loop, true,
48 factory_->GetShutDownEvent())); 48 factory_->GetShutDownEvent()));
49 49
50 sync_filter_ = new IPC::SyncMessageFilter( 50 sync_filter_ = new IPC::SyncMessageFilter(
51 factory_->GetShutDownEvent()); 51 factory_->GetShutDownEvent());
52 52
53 channel_->AddFilter(sync_filter_.get()); 53 channel_->AddFilter(sync_filter_.get());
54 54
55 channel_filter_ = new MessageFilter(this); 55 channel_filter_ = new MessageFilter(AsWeakPtr(), factory_);
56 56
57 // Install the filter last, because we intercept all leftover 57 // Install the filter last, because we intercept all leftover
58 // messages. 58 // messages.
59 channel_->AddFilter(channel_filter_.get()); 59 channel_->AddFilter(channel_filter_.get());
60 60
61 // It is safe to send IPC messages before the channel completes the connection 61 // It is safe to send IPC messages before the channel completes the connection
62 // and receives the hello message from the GPU process. The messages get 62 // and receives the hello message from the GPU process. The messages get
63 // cached. 63 // cached.
64 state_ = kConnected; 64 state_ = kConnected;
65 } 65 }
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 names.end()); 309 names.end());
310 } 310 }
311 311
312 int32 GpuChannelHost::ReserveTransferBufferId() { 312 int32 GpuChannelHost::ReserveTransferBufferId() {
313 return next_transfer_buffer_id_.GetNext(); 313 return next_transfer_buffer_id_.GetNext();
314 } 314 }
315 315
316 GpuChannelHost::~GpuChannelHost() {} 316 GpuChannelHost::~GpuChannelHost() {}
317 317
318 318
319 GpuChannelHost::MessageFilter::MessageFilter(GpuChannelHost* parent) 319 GpuChannelHost::MessageFilter::MessageFilter(
320 : parent_(parent) { 320 base::WeakPtr<GpuChannelHost> parent,
321 GpuChannelHostFactory* factory)
322 : parent_(parent),
323 factory_(factory) {
321 } 324 }
322 325
323 GpuChannelHost::MessageFilter::~MessageFilter() {} 326 GpuChannelHost::MessageFilter::~MessageFilter() {}
324 327
325 void GpuChannelHost::MessageFilter::AddRoute( 328 void GpuChannelHost::MessageFilter::AddRoute(
326 int route_id, 329 int route_id,
327 base::WeakPtr<IPC::Listener> listener, 330 base::WeakPtr<IPC::Listener> listener,
328 scoped_refptr<MessageLoopProxy> loop) { 331 scoped_refptr<MessageLoopProxy> loop) {
329 DCHECK(parent_->factory_->IsIOThread()); 332 DCHECK(factory_->IsIOThread());
330 DCHECK(listeners_.find(route_id) == listeners_.end()); 333 DCHECK(listeners_.find(route_id) == listeners_.end());
331 GpuListenerInfo info; 334 GpuListenerInfo info;
332 info.listener = listener; 335 info.listener = listener;
333 info.loop = loop; 336 info.loop = loop;
334 listeners_[route_id] = info; 337 listeners_[route_id] = info;
335 } 338 }
336 339
337 void GpuChannelHost::MessageFilter::RemoveRoute(int route_id) { 340 void GpuChannelHost::MessageFilter::RemoveRoute(int route_id) {
338 DCHECK(parent_->factory_->IsIOThread()); 341 DCHECK(factory_->IsIOThread());
339 ListenerMap::iterator it = listeners_.find(route_id); 342 ListenerMap::iterator it = listeners_.find(route_id);
340 if (it != listeners_.end()) 343 if (it != listeners_.end())
341 listeners_.erase(it); 344 listeners_.erase(it);
342 } 345 }
343 346
344 bool GpuChannelHost::MessageFilter::OnMessageReceived( 347 bool GpuChannelHost::MessageFilter::OnMessageReceived(
345 const IPC::Message& message) { 348 const IPC::Message& message) {
346 DCHECK(parent_->factory_->IsIOThread()); 349 DCHECK(factory_->IsIOThread());
347 350
348 // Never handle sync message replies or we will deadlock here. 351 // Never handle sync message replies or we will deadlock here.
349 if (message.is_reply()) 352 if (message.is_reply())
350 return false; 353 return false;
351 354
352 if (message.routing_id() == MSG_ROUTING_CONTROL) { 355 if (message.routing_id() == MSG_ROUTING_CONTROL) {
353 MessageLoop* main_loop = parent_->factory_->GetMainLoop(); 356 MessageLoop* main_loop = factory_->GetMainLoop();
354 main_loop->PostTask(FROM_HERE, 357 main_loop->PostTask(FROM_HERE,
355 base::Bind(&GpuChannelHost::OnMessageReceived, 358 base::Bind(&GpuChannelHost::OnMessageReceived,
356 parent_, 359 parent_,
357 message)); 360 message));
358 return true; 361 return true;
359 } 362 }
360 363
361 ListenerMap::iterator it = listeners_.find(message.routing_id()); 364 ListenerMap::iterator it = listeners_.find(message.routing_id());
362 365
363 if (it != listeners_.end()) { 366 if (it != listeners_.end()) {
364 const GpuListenerInfo& info = it->second; 367 const GpuListenerInfo& info = it->second;
365 info.loop->PostTask( 368 info.loop->PostTask(
366 FROM_HERE, 369 FROM_HERE,
367 base::Bind( 370 base::Bind(
368 base::IgnoreResult(&IPC::Listener::OnMessageReceived), 371 base::IgnoreResult(&IPC::Listener::OnMessageReceived),
369 info.listener, 372 info.listener,
370 message)); 373 message));
371 } 374 }
372 375
373 return true; 376 return true;
374 } 377 }
375 378
376 void GpuChannelHost::MessageFilter::OnChannelError() { 379 void GpuChannelHost::MessageFilter::OnChannelError() {
377 DCHECK(parent_->factory_->IsIOThread()); 380 DCHECK(factory_->IsIOThread());
378 381
379 // Post the task to signal the GpuChannelHost before the proxies. That way, if 382 // Post the task to signal the GpuChannelHost before the proxies. That way, if
380 // they themselves post a task to recreate the context, they will not try to 383 // they themselves post a task to recreate the context, they will not try to
381 // re-use this channel host before it has a chance to mark itself lost. 384 // re-use this channel host before it has a chance to mark itself lost.
382 MessageLoop* main_loop = parent_->factory_->GetMainLoop(); 385 MessageLoop* main_loop = factory_->GetMainLoop();
383 main_loop->PostTask(FROM_HERE, 386 main_loop->PostTask(FROM_HERE,
384 base::Bind(&GpuChannelHost::OnChannelError, parent_)); 387 base::Bind(&GpuChannelHost::OnChannelError, parent_));
385 // Inform all the proxies that an error has occurred. This will be reported 388 // Inform all the proxies that an error has occurred. This will be reported
386 // via OpenGL as a lost context. 389 // via OpenGL as a lost context.
387 for (ListenerMap::iterator it = listeners_.begin(); 390 for (ListenerMap::iterator it = listeners_.begin();
388 it != listeners_.end(); 391 it != listeners_.end();
389 it++) { 392 it++) {
390 const GpuListenerInfo& info = it->second; 393 const GpuListenerInfo& info = it->second;
391 info.loop->PostTask( 394 info.loop->PostTask(
392 FROM_HERE, 395 FROM_HERE,
393 base::Bind(&IPC::Listener::OnChannelError, info.listener)); 396 base::Bind(&IPC::Listener::OnChannelError, info.listener));
394 } 397 }
395 398
396 listeners_.clear(); 399 listeners_.clear();
397 } 400 }
398 401
399 } // namespace content 402 } // namespace content
OLDNEW
« chrome/test/gpu/gpu_feature_browsertest.cc ('K') | « content/common/gpu/client/gpu_channel_host.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698