diff options
| author | sky <sky@chromium.org> | 2016-03-24 14:59:49 -0700 |
|---|---|---|
| committer | Commit bot <commit-bot@chromium.org> | 2016-03-24 22:01:03 +0000 |
| commit | 18a65ed087f1ee0e870fde69924662f86ad5f211 (patch) | |
| tree | 71b777e85bc5bcf756990f7abe8e1051b620f859 | |
| parent | b4496c7923f03200fbae07e2512e93a2107f8929 (diff) | |
| download | chromium_src-18a65ed087f1ee0e870fde69924662f86ad5f211.zip chromium_src-18a65ed087f1ee0e870fde69924662f86ad5f211.tar.gz chromium_src-18a65ed087f1ee0e870fde69924662f86ad5f211.tar.bz2 | |
Fixes two shutdown bugs in Mus:
. CommandBufferImpl::OnConnectionError() needs to handle the
possibility of |driver_| having not been created yet.
. CommandBufferLocal::Destroy() needs to wait for the deletion before
continuing. If it doesn't the AcceleratedWidget may be accessed
after destruction, when the AcceleratedWidget is no longer valid.
BUG=581733
TEST=none
R=fsamuel@chromium.org
Review URL: https://codereview.chromium.org/1834813003
Cr-Commit-Position: refs/heads/master@{#383159}
| -rw-r--r-- | components/mus/gles2/command_buffer_impl.cc | 19 | ||||
| -rw-r--r-- | components/mus/gles2/command_buffer_impl.h | 1 | ||||
| -rw-r--r-- | components/mus/gles2/command_buffer_local.cc | 11 | ||||
| -rw-r--r-- | components/mus/gles2/command_buffer_local.h | 2 |
4 files changed, 25 insertions, 8 deletions
diff --git a/components/mus/gles2/command_buffer_impl.cc b/components/mus/gles2/command_buffer_impl.cc index adb5845..13ce77c 100644 --- a/components/mus/gles2/command_buffer_impl.cc +++ b/components/mus/gles2/command_buffer_impl.cc @@ -280,10 +280,17 @@ void CommandBufferImpl::OnConnectionError() { binding_.reset(); // Objects we own (such as CommandBufferDriver) need to be destroyed on the - // thread we were created on. - gpu_state_->command_buffer_task_runner()->PostTask( - driver_.get(), base::Bind(&CommandBufferImpl::DeleteOnGpuThread, - base::Unretained(this))); + // thread we were created on. It's entirely possible we haven't or are in the + // process of creating |driver_|. + if (driver_) { + gpu_state_->command_buffer_task_runner()->PostTask( + driver_.get(), base::Bind(&CommandBufferImpl::DeleteOnGpuThread, + base::Unretained(this))); + } else { + gpu_state_->command_buffer_task_runner()->task_runner()->PostTask( + FROM_HERE, base::Bind(&CommandBufferImpl::DeleteOnGpuThread2, + base::Unretained(this))); + } } bool CommandBufferImpl::DeleteOnGpuThread() { @@ -291,4 +298,8 @@ bool CommandBufferImpl::DeleteOnGpuThread() { return true; } +void CommandBufferImpl::DeleteOnGpuThread2() { + delete this; +} + } // namespace mus diff --git a/components/mus/gles2/command_buffer_impl.h b/components/mus/gles2/command_buffer_impl.h index ad57596..6bdbef8 100644 --- a/components/mus/gles2/command_buffer_impl.h +++ b/components/mus/gles2/command_buffer_impl.h @@ -102,6 +102,7 @@ class CommandBufferImpl : public mojom::CommandBuffer { void OnConnectionError(); bool DeleteOnGpuThread(); + void DeleteOnGpuThread2(); scoped_refptr<GpuState> gpu_state_; scoped_ptr<CommandBufferDriver> driver_; diff --git a/components/mus/gles2/command_buffer_local.cc b/components/mus/gles2/command_buffer_local.cc index b0e09a4..d4b2b03 100644 --- a/components/mus/gles2/command_buffer_local.cc +++ b/components/mus/gles2/command_buffer_local.cc @@ -96,10 +96,14 @@ void CommandBufferLocal::Destroy() { weak_factory_.InvalidateWeakPtrs(); // CommandBufferLocal is initialized on the GPU thread with // InitializeOnGpuThread(), so we need delete memebers on the GPU thread - // too. + // too. Additionally we need to make sure we are deleted before returning, + // otherwise we may attempt to use the AcceleratedWidget which has since been + // destroyed. + base::WaitableEvent event(true, false); gpu_state_->command_buffer_task_runner()->PostTask( driver_.get(), base::Bind(&CommandBufferLocal::DeleteOnGpuThread, - base::Unretained(this))); + base::Unretained(this), &event)); + event.Wait(); } bool CommandBufferLocal::Initialize() { @@ -512,8 +516,9 @@ bool CommandBufferLocal::MakeProgressOnGpuThread( return true; } -bool CommandBufferLocal::DeleteOnGpuThread() { +bool CommandBufferLocal::DeleteOnGpuThread(base::WaitableEvent* event) { delete this; + event->Signal(); return true; } diff --git a/components/mus/gles2/command_buffer_local.h b/components/mus/gles2/command_buffer_local.h index 2777654..bfc9e77 100644 --- a/components/mus/gles2/command_buffer_local.h +++ b/components/mus/gles2/command_buffer_local.h @@ -128,7 +128,7 @@ class CommandBufferLocal : public gpu::CommandBuffer, bool DestroyImageOnGpuThread(int32_t id); bool MakeProgressOnGpuThread(base::WaitableEvent* event, gpu::CommandBuffer::State* state); - bool DeleteOnGpuThread(); + bool DeleteOnGpuThread(base::WaitableEvent* event); bool SignalQueryOnGpuThread(uint32_t query_id, const base::Closure& callback); // Helper functions are called in the client thread. |
