summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorboliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-28 05:45:41 +0000
committerboliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-28 05:45:41 +0000
commitdecf5cf18fff955f767ad8efb578a364d978a69f (patch)
tree6b6512cdf2b953381cff31503ea751544e19a1d6
parent5f8f374cc79be7d1b9d9c13cc4ffdb06ef16990c (diff)
downloadchromium_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
-rw-r--r--android_webview/browser/gl_view_renderer_manager.cc13
-rw-r--r--android_webview/browser/gl_view_renderer_manager.h6
-rw-r--r--android_webview/browser/hardware_renderer.cc11
-rw-r--r--android_webview/browser/hardware_renderer.h4
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwContents.java18
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);