From 8ebac2451103d0c51dbfb5f109235f458012984c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20Kalliom=C3=A4ki?= Date: Wed, 8 Nov 2017 17:13:13 +0100 Subject: [PATCH] Fix a crash in EglRenderer.removeFrameListener. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The crash occured if removeFrameListener was called after releasing the EglRenderer. Bug: b/69040588 Change-Id: I90acc3b280d2009e5f13bb8836a288eb20c7d1d0 Reviewed-on: https://webrtc-review.googlesource.com/21380 Reviewed-by: Magnus Jedvert Commit-Queue: Sami Kalliomäki Cr-Commit-Position: refs/heads/master@{#20620} --- sdk/android/api/org/webrtc/EglRenderer.java | 28 +++++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/sdk/android/api/org/webrtc/EglRenderer.java b/sdk/android/api/org/webrtc/EglRenderer.java index abf2f4a9f4..ba39971e5b 100644 --- a/sdk/android/api/org/webrtc/EglRenderer.java +++ b/sdk/android/api/org/webrtc/EglRenderer.java @@ -242,6 +242,7 @@ public class EglRenderer implements VideoRenderer.Callbacks, VideoSink { eglBase.release(); eglBase = null; } + frameListeners.clear(); eglCleanupBarrier.countDown(); }); final Looper renderLooper = renderThreadHandler.getLooper(); @@ -400,19 +401,24 @@ public class EglRenderer implements VideoRenderer.Callbacks, VideoSink { * @param runnable The callback to remove. */ public void removeFrameListener(final FrameListener listener) { - if (Thread.currentThread() == renderThreadHandler.getLooper().getThread()) { - throw new RuntimeException("removeFrameListener must not be called on the render thread."); - } final CountDownLatch latch = new CountDownLatch(1); - postToRenderThread(() -> { - latch.countDown(); - final Iterator iter = frameListeners.iterator(); - while (iter.hasNext()) { - if (iter.next().listener == listener) { - iter.remove(); - } + synchronized (handlerLock) { + if (renderThreadHandler == null) { + return; } - }); + if (Thread.currentThread() == renderThreadHandler.getLooper().getThread()) { + throw new RuntimeException("removeFrameListener must not be called on the render thread."); + } + postToRenderThread(() -> { + latch.countDown(); + final Iterator iter = frameListeners.iterator(); + while (iter.hasNext()) { + if (iter.next().listener == listener) { + iter.remove(); + } + } + }); + } ThreadUtils.awaitUninterruptibly(latch); }