From fd7194acb3e20a00f2d51ac890a7ac6ad93828d8 Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Thu, 7 Sep 2017 14:44:40 -0700 Subject: [PATCH] Fix NativeCallbackThread race condition. Bug: b/65286959 Test: instrumentation Change-Id: I0086a362b9b916d87118ed478aa8222874df19b1 --- .../radio/tests/functional/RadioTunerTest.java | 15 +++++++++++++++ .../jni/BroadcastRadio/NativeCallbackThread.cpp | 16 +++++++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/functional/RadioTunerTest.java b/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/functional/RadioTunerTest.java index c70724019edb1..a8d516405ea2a 100644 --- a/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/functional/RadioTunerTest.java +++ b/core/tests/BroadcastRadioTests/src/android/hardware/radio/tests/functional/RadioTunerTest.java @@ -274,6 +274,21 @@ public class RadioTunerTest { verify(mCallback, timeout(kTuneCallbackTimeoutMs)).onProgramInfoChanged(any()); } + @Test + public void testStepLoop() { + openTuner(); + + for (int i = 0; i < 10; i++) { + Log.d(TAG, "step loop iteration " + (i + 1)); + + int ret = mRadioTuner.step(RadioTuner.DIRECTION_DOWN, true); + assertEquals(RadioManager.STATUS_OK, ret); + verify(mCallback, timeout(kTuneCallbackTimeoutMs)).onProgramInfoChanged(any()); + + resetCallback(); + } + } + @Test public void testTuneAndGetPI() { openTuner(); diff --git a/services/core/jni/BroadcastRadio/NativeCallbackThread.cpp b/services/core/jni/BroadcastRadio/NativeCallbackThread.cpp index 85ec9e07e39e3..81d46f39d84ac 100644 --- a/services/core/jni/BroadcastRadio/NativeCallbackThread.cpp +++ b/services/core/jni/BroadcastRadio/NativeCallbackThread.cpp @@ -48,15 +48,19 @@ void NativeCallbackThread::threadLoop() { return; } - while (!mExiting) { - ALOGV("Waiting for task..."); + while (true) { Task task; { unique_lock lk(mQueueMutex); - mQueueCond.wait(lk); - if (mExiting) break; - if (mQueue.empty()) continue; + if (mExiting) break; + if (mQueue.empty()) { + ALOGV("Waiting for task..."); + mQueueCond.wait(lk); + if (mExiting) break; + if (mQueue.empty()) continue; + } + task = mQueue.front(); mQueue.pop(); } @@ -74,6 +78,7 @@ void NativeCallbackThread::threadLoop() { ALOGE_IF(res != JNI_OK, "Couldn't detach thread"); ALOGV("Native callback thread %p finished", this); + ALOGD_IF(!mQueue.empty(), "Skipped execution of %zu tasks", mQueue.size()); } void NativeCallbackThread::enqueue(const Task &task) { @@ -84,6 +89,7 @@ void NativeCallbackThread::enqueue(const Task &task) { return; } + ALOGV("Adding task to the queue..."); mQueue.push(task); mQueueCond.notify_one(); }