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 692fb8e38a8ca88b43c31eb43f53c9779e5a793e..24628f5b12d784e9b81508c6c2c603b09087cb79 100644 |
--- a/gpu/command_buffer/service/in_process_command_buffer.cc |
+++ b/gpu/command_buffer/service/in_process_command_buffer.cc |
@@ -221,6 +221,21 @@ gfx::GpuMemoryBufferHandle ShareGpuMemoryBufferToGpuThread( |
} |
} |
+scoped_refptr<InProcessCommandBuffer::Service> GetInitialService( |
+ const scoped_refptr<InProcessCommandBuffer::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; |
+} |
+ |
} // anonyous namespace |
InProcessCommandBuffer::Service::Service() {} |
@@ -271,7 +286,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(); |