Index: gpu/command_buffer/service/in_process_command_buffer.cc |
diff --git a/gpu/command_buffer/service/in_process_command_buffer.cc b/gpu/command_buffer/service/in_process_command_buffer.cc |
index 5b325ab12256706f718a5c7c4d229d61beb2cf02..3d6913e3d0fe3891e0006ee9e74753c6331cad7e 100644 |
--- a/gpu/command_buffer/service/in_process_command_buffer.cc |
+++ b/gpu/command_buffer/service/in_process_command_buffer.cc |
@@ -271,7 +271,7 @@ InProcessCommandBuffer::InProcessCommandBuffer( |
last_put_offset_(-1), |
gpu_memory_buffer_manager_(nullptr), |
flush_event_(false, false), |
- service_(service.get() ? service : g_default_service.Get().gpu_thread), |
+ service_(GetInitialService(service)), |
gpu_thread_weak_ptr_factory_(this) { |
DCHECK(service_.get()); |
next_image_id_.GetNext(); |
@@ -281,6 +281,22 @@ InProcessCommandBuffer::~InProcessCommandBuffer() { |
Destroy(); |
} |
+scoped_refptr<InProcessCommandBuffer::Service> |
+InProcessCommandBuffer::GetInitialService( |
+ const scoped_refptr<Service>& service) { |
+ if (service) |
+ return service; |
+ |
+ // Call base::ThreadTaskRunnerHandle::IsSet() to ensure that it is |
+ // instantiated before we create the GPU thread, otherwise shutdown order will |
+ // delete the ThreadTaskRunnerHandle before the GPU thread's message loop, |
+ // and when the message loop is shutdown, it will recreate |
+ // ThreadTaskRunnerHandle, which will re-add a new task to the, AtExitManager, |
+ // which causes a deadlock because it's already locked. |
+ base::ThreadTaskRunnerHandle::IsSet(); |
+ return g_default_service.Get().gpu_thread; |
+} |
+ |
void InProcessCommandBuffer::OnResizeView(gfx::Size size, float scale_factor) { |
CheckSequencedThread(); |
DCHECK(!surface_->IsOffscreen()); |