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

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

Issue 1128233004: Fix GpuChannelHost destruction and races (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 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
« no previous file with comments | « content/common/gpu/client/gpu_channel_host.h ('k') | content/renderer/render_thread_impl.cc » ('j') | 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) 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 <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 : factory_(factory), 61 : factory_(factory),
62 gpu_info_(gpu_info), 62 gpu_info_(gpu_info),
63 gpu_memory_buffer_manager_(gpu_memory_buffer_manager) { 63 gpu_memory_buffer_manager_(gpu_memory_buffer_manager) {
64 next_transfer_buffer_id_.GetNext(); 64 next_transfer_buffer_id_.GetNext();
65 next_image_id_.GetNext(); 65 next_image_id_.GetNext();
66 next_route_id_.GetNext(); 66 next_route_id_.GetNext();
67 } 67 }
68 68
69 void GpuChannelHost::Connect(const IPC::ChannelHandle& channel_handle, 69 void GpuChannelHost::Connect(const IPC::ChannelHandle& channel_handle,
70 base::WaitableEvent* shutdown_event) { 70 base::WaitableEvent* shutdown_event) {
71 DCHECK(factory_->IsMainThread());
71 // Open a channel to the GPU process. We pass NULL as the main listener here 72 // Open a channel to the GPU process. We pass NULL as the main listener here
72 // since we need to filter everything to route it to the right thread. 73 // since we need to filter everything to route it to the right thread.
73 scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy(); 74 scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy();
74 channel_ = IPC::SyncChannel::Create(channel_handle, 75 channel_ = IPC::SyncChannel::Create(channel_handle,
75 IPC::Channel::MODE_CLIENT, 76 IPC::Channel::MODE_CLIENT,
76 NULL, 77 NULL,
77 io_loop.get(), 78 io_loop.get(),
78 true, 79 true,
79 shutdown_event); 80 shutdown_event);
80 81
(...skipping 18 matching lines...) Expand all
99 100
100 // Currently we need to choose between two different mechanisms for sending. 101 // Currently we need to choose between two different mechanisms for sending.
101 // On the main thread we use the regular channel Send() method, on another 102 // On the main thread we use the regular channel Send() method, on another
102 // thread we use SyncMessageFilter. We also have to be careful interpreting 103 // thread we use SyncMessageFilter. We also have to be careful interpreting
103 // IsMainThread() since it might return false during shutdown, 104 // IsMainThread() since it might return false during shutdown,
104 // impl we are actually calling from the main thread (discard message then). 105 // impl we are actually calling from the main thread (discard message then).
105 // 106 //
106 // TODO: Can we just always use sync_filter_ since we setup the channel 107 // TODO: Can we just always use sync_filter_ since we setup the channel
107 // without a main listener? 108 // without a main listener?
108 if (factory_->IsMainThread()) { 109 if (factory_->IsMainThread()) {
110 // channel_ is only modified on the main thread, so we don't need to take a
111 // lock here.
112 if (!channel_) {
113 DVLOG(1) << "GpuChannelHost::Send failed: Channel already destroyed";
114 return false;
115 }
109 // http://crbug.com/125264 116 // http://crbug.com/125264
110 base::ThreadRestrictions::ScopedAllowWait allow_wait; 117 base::ThreadRestrictions::ScopedAllowWait allow_wait;
111 bool result = channel_->Send(message.release()); 118 bool result = channel_->Send(message.release());
112 if (!result) 119 if (!result)
113 DVLOG(1) << "GpuChannelHost::Send failed: Channel::Send failed"; 120 DVLOG(1) << "GpuChannelHost::Send failed: Channel::Send failed";
114 return result; 121 return result;
115 } 122 }
116 123
117 bool result = sync_filter_->Send(message.release()); 124 bool result = sync_filter_->Send(message.release());
118 return result; 125 return result;
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 273
267 AutoLock lock(context_lock_); 274 AutoLock lock(context_lock_);
268 proxies_.erase(route_id); 275 proxies_.erase(route_id);
269 if (flush_info_.flush_pending && flush_info_.route_id == route_id) 276 if (flush_info_.flush_pending && flush_info_.route_id == route_id)
270 flush_info_.flush_pending = false; 277 flush_info_.flush_pending = false;
271 278
272 delete command_buffer; 279 delete command_buffer;
273 } 280 }
274 281
275 void GpuChannelHost::DestroyChannel() { 282 void GpuChannelHost::DestroyChannel() {
276 // channel_ must be destroyed on the main thread. 283 DCHECK(factory_->IsMainThread());
277 if (channel_.get() && !factory_->IsMainThread()) 284 AutoLock lock(context_lock_);
278 factory_->GetMainLoop()->DeleteSoon(FROM_HERE, channel_.release());
279 channel_.reset(); 285 channel_.reset();
280 } 286 }
281 287
282 void GpuChannelHost::AddRoute( 288 void GpuChannelHost::AddRoute(
283 int route_id, base::WeakPtr<IPC::Listener> listener) { 289 int route_id, base::WeakPtr<IPC::Listener> listener) {
284 DCHECK(MessageLoopProxy::current().get()); 290 DCHECK(MessageLoopProxy::current().get());
285 291
286 scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy(); 292 scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy();
287 io_loop->PostTask(FROM_HERE, 293 io_loop->PostTask(FROM_HERE,
288 base::Bind(&GpuChannelHost::MessageFilter::AddRoute, 294 base::Bind(&GpuChannelHost::MessageFilter::AddRoute,
289 channel_filter_.get(), route_id, listener, 295 channel_filter_.get(), route_id, listener,
290 MessageLoopProxy::current())); 296 MessageLoopProxy::current()));
291 } 297 }
292 298
293 void GpuChannelHost::RemoveRoute(int route_id) { 299 void GpuChannelHost::RemoveRoute(int route_id) {
294 scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy(); 300 scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy();
295 io_loop->PostTask(FROM_HERE, 301 io_loop->PostTask(FROM_HERE,
296 base::Bind(&GpuChannelHost::MessageFilter::RemoveRoute, 302 base::Bind(&GpuChannelHost::MessageFilter::RemoveRoute,
297 channel_filter_.get(), route_id)); 303 channel_filter_.get(), route_id));
298 } 304 }
299 305
300 base::SharedMemoryHandle GpuChannelHost::ShareToGpuProcess( 306 base::SharedMemoryHandle GpuChannelHost::ShareToGpuProcess(
301 base::SharedMemoryHandle source_handle) { 307 base::SharedMemoryHandle source_handle) {
302 if (IsLost()) 308 if (IsLost())
303 return base::SharedMemory::NULLHandle(); 309 return base::SharedMemory::NULLHandle();
304 310
305 #if defined(OS_WIN) 311 #if defined(OS_WIN)
306 // Windows needs to explicitly duplicate the handle out to another process. 312 // Windows needs to explicitly duplicate the handle out to another process.
307 base::SharedMemoryHandle target_handle; 313 base::SharedMemoryHandle target_handle;
314 base::ProcessId peer_pid;
315 {
316 AutoLock lock(context_lock_);
317 if (!channel_)
318 return base::SharedMemory::NULLHandle();
319 peer_pid = channel_->GetPeerPID();
320 }
308 if (!BrokerDuplicateHandle(source_handle, 321 if (!BrokerDuplicateHandle(source_handle,
309 channel_->GetPeerPID(), 322 peer_pid,
310 &target_handle, 323 &target_handle,
311 FILE_GENERIC_READ | FILE_GENERIC_WRITE, 324 FILE_GENERIC_READ | FILE_GENERIC_WRITE,
312 0)) { 325 0)) {
313 return base::SharedMemory::NULLHandle(); 326 return base::SharedMemory::NULLHandle();
314 } 327 }
315 328
316 return target_handle; 329 return target_handle;
317 #else 330 #else
318 int duped_handle = HANDLE_EINTR(dup(source_handle.fd)); 331 int duped_handle = HANDLE_EINTR(dup(source_handle.fd));
319 if (duped_handle < 0) 332 if (duped_handle < 0)
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 364
352 int32 GpuChannelHost::ReserveImageId() { 365 int32 GpuChannelHost::ReserveImageId() {
353 return next_image_id_.GetNext(); 366 return next_image_id_.GetNext();
354 } 367 }
355 368
356 int32 GpuChannelHost::GenerateRouteID() { 369 int32 GpuChannelHost::GenerateRouteID() {
357 return next_route_id_.GetNext(); 370 return next_route_id_.GetNext();
358 } 371 }
359 372
360 GpuChannelHost::~GpuChannelHost() { 373 GpuChannelHost::~GpuChannelHost() {
361 DestroyChannel(); 374 #if DCHECK_IS_ON()
375 AutoLock lock(context_lock_);
376 DCHECK(!channel_)
377 << "GpuChannelHost::DestroyChannel must be called before destruction.";
378 #endif
362 } 379 }
363 380
364 GpuChannelHost::MessageFilter::MessageFilter() 381 GpuChannelHost::MessageFilter::MessageFilter()
365 : lost_(false) { 382 : lost_(false) {
366 } 383 }
367 384
368 GpuChannelHost::MessageFilter::~MessageFilter() {} 385 GpuChannelHost::MessageFilter::~MessageFilter() {}
369 386
370 void GpuChannelHost::MessageFilter::AddRoute( 387 void GpuChannelHost::MessageFilter::AddRoute(
371 int route_id, 388 int route_id,
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 443
427 listeners_.clear(); 444 listeners_.clear();
428 } 445 }
429 446
430 bool GpuChannelHost::MessageFilter::IsLost() const { 447 bool GpuChannelHost::MessageFilter::IsLost() const {
431 AutoLock lock(lock_); 448 AutoLock lock(lock_);
432 return lost_; 449 return lost_;
433 } 450 }
434 451
435 } // namespace content 452 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/client/gpu_channel_host.h ('k') | content/renderer/render_thread_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698