summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsky <sky@chromium.org>2016-03-24 14:59:49 -0700
committerCommit bot <commit-bot@chromium.org>2016-03-24 22:01:03 +0000
commit18a65ed087f1ee0e870fde69924662f86ad5f211 (patch)
tree71b777e85bc5bcf756990f7abe8e1051b620f859
parentb4496c7923f03200fbae07e2512e93a2107f8929 (diff)
downloadchromium_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.cc19
-rw-r--r--components/mus/gles2/command_buffer_impl.h1
-rw-r--r--components/mus/gles2/command_buffer_local.cc11
-rw-r--r--components/mus/gles2/command_buffer_local.h2
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.