diff options
author | boliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-28 05:45:41 +0000 |
---|---|---|
committer | boliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-28 05:45:41 +0000 |
commit | decf5cf18fff955f767ad8efb578a364d978a69f (patch) | |
tree | 6b6512cdf2b953381cff31503ea751544e19a1d6 | |
parent | 5f8f374cc79be7d1b9d9c13cc4ffdb06ef16990c (diff) | |
download | chromium_src-decf5cf18fff955f767ad8efb578a364d978a69f.zip chromium_src-decf5cf18fff955f767ad8efb578a364d978a69f.tar.gz chromium_src-decf5cf18fff955f767ad8efb578a364d978a69f.tar.bz2 |
Leak instead of deadlock if executeHardwareAction fails
If executeHardwareAction fails in onDetachedFromWindow, then
HardwareRenderer destructor will deadlock later when being destroyed on
UI thread. In this case, run the destructor on UI without deadlock but
leak GL resources instead.
Achieve this by running always running release gl even on UI thread, and
making the allow_gl global to be a true thread local, which can be set
to true on UI thread.
BUG=
TBR=benm
Review URL: https://codereview.chromium.org/255783007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@266429 0039d316-1c4b-4281-b951-d872f2087c98
5 files changed, 17 insertions, 35 deletions
diff --git a/android_webview/browser/gl_view_renderer_manager.cc b/android_webview/browser/gl_view_renderer_manager.cc index 13a60fd..1aa4199 100644 --- a/android_webview/browser/gl_view_renderer_manager.cc +++ b/android_webview/browser/gl_view_renderer_manager.cc @@ -25,20 +25,7 @@ GLViewRendererManager::GLViewRendererManager() {} GLViewRendererManager::~GLViewRendererManager() {} -bool GLViewRendererManager::OnRenderThread() const { - AutoLock auto_lock(lock_); - return render_thread_.is_equal(base::PlatformThread::CurrentHandle()); -} - -void GLViewRendererManager::MarkRenderThread() { - lock_.AssertAcquired(); - if (render_thread_.is_null()) - render_thread_ = base::PlatformThread::CurrentHandle(); - DCHECK(render_thread_.is_equal(base::PlatformThread::CurrentHandle())); -} - GLViewRendererManager::Key GLViewRendererManager::PushBack(RendererType view) { - MarkRenderThread(); DCHECK(mru_list_.end() == std::find(mru_list_.begin(), mru_list_.end(), view)); mru_list_.push_back(view); diff --git a/android_webview/browser/gl_view_renderer_manager.h b/android_webview/browser/gl_view_renderer_manager.h index 1965c3e..1e1a1df 100644 --- a/android_webview/browser/gl_view_renderer_manager.h +++ b/android_webview/browser/gl_view_renderer_manager.h @@ -28,9 +28,6 @@ class GLViewRendererManager { static GLViewRendererManager* GetInstance(); - // TODO(boliu): Move RenderThread checking out of this class. - bool OnRenderThread() const; - Key PushBack(RendererType view); // |key| must be already in manager. Move renderer corresponding to |key| to @@ -47,10 +44,7 @@ class GLViewRendererManager { GLViewRendererManager(); ~GLViewRendererManager(); - void MarkRenderThread(); - mutable base::Lock lock_; - base::PlatformThreadHandle render_thread_; ListType mru_list_; DISALLOW_COPY_AND_ASSIGN(GLViewRendererManager); diff --git a/android_webview/browser/hardware_renderer.cc b/android_webview/browser/hardware_renderer.cc index a45da7f..6136aea 100644 --- a/android_webview/browser/hardware_renderer.cc +++ b/android_webview/browser/hardware_renderer.cc @@ -206,23 +206,22 @@ void HardwareRenderer::CalculateTileMemoryPolicy() { namespace internal { -bool ScopedAllowGL::allow_gl = false; +base::LazyInstance<base::ThreadLocalBoolean> ScopedAllowGL::allow_gl; // static bool ScopedAllowGL::IsAllowed() { - return GLViewRendererManager::GetInstance()->OnRenderThread() && allow_gl; + return allow_gl.Get().Get(); } ScopedAllowGL::ScopedAllowGL() { - DCHECK(GLViewRendererManager::GetInstance()->OnRenderThread()); - DCHECK(!allow_gl); - allow_gl = true; + DCHECK(!allow_gl.Get().Get()); + allow_gl.Get().Set(true); if (g_service.Get()) g_service.Get()->RunTasks(); } -ScopedAllowGL::~ScopedAllowGL() { allow_gl = false; } +ScopedAllowGL::~ScopedAllowGL() { allow_gl.Get().Set(false); } DeferredGpuCommandService::DeferredGpuCommandService() {} diff --git a/android_webview/browser/hardware_renderer.h b/android_webview/browser/hardware_renderer.h index 4f226d2..09580eb 100644 --- a/android_webview/browser/hardware_renderer.h +++ b/android_webview/browser/hardware_renderer.h @@ -9,7 +9,9 @@ #include "android_webview/browser/gl_view_renderer_manager.h" #include "android_webview/browser/shared_renderer_state.h" +#include "base/lazy_instance.h" #include "base/memory/ref_counted.h" +#include "base/threading/thread_local.h" #include "content/public/browser/android/synchronous_compositor.h" struct AwDrawGLInfo; @@ -61,7 +63,7 @@ class ScopedAllowGL { static bool IsAllowed(); private: - static bool allow_gl; + static base::LazyInstance<base::ThreadLocalBoolean> allow_gl; DISALLOW_COPY_AND_ASSIGN(ScopedAllowGL); }; diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java index 832e907..f6eaa03 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java @@ -1615,16 +1615,16 @@ public class AwContents { mIsAttachedToWindow = false; hideAutofillPopup(); if (mNativeAwContents != 0) { - if (mContainerView.isHardwareAccelerated()) { - boolean result = mInternalAccessAdapter.executeHardwareAction(new Runnable() { - @Override - public void run() { - nativeReleaseHardwareDrawOnRenderThread(mNativeAwContents); - } - }); - if (!result) { - Log.d(TAG, "executeHardwareAction failed"); + Runnable releaseHardware = new Runnable() { + @Override + public void run() { + nativeReleaseHardwareDrawOnRenderThread(mNativeAwContents); } + }; + boolean result = mInternalAccessAdapter.executeHardwareAction(releaseHardware); + if (!result) { + Log.e(TAG, "May leak or deadlock. Leaked window?"); + releaseHardware.run(); } nativeOnDetachedFromWindow(mNativeAwContents); |