From eaeced3383fc398e657b02452952f1a3db6285a1 Mon Sep 17 00:00:00 2001 From: Andy Hung Date: Tue, 3 Mar 2020 13:40:49 -0800 Subject: [PATCH] SoundPool: Fix StreamManager JavaThread shutdown std::future destructor only blocks for ready when created by std::async, so do a wait in the JavaThread destructor. Do not signal that the thread is closed until we really are finished with all member variable access. This fixes a rare race condition. Test: SoundPool stress test Test: SoundPoolAacTest SoundPoolHapticTest SoundPoolMidiTest SoundPoolOggTest Bug: 150517918 Change-Id: I412143726956ee100069f711dd39b1d59ac100b0 --- media/jni/soundpool/StreamManager.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/media/jni/soundpool/StreamManager.h b/media/jni/soundpool/StreamManager.h index 8c98ac992f75f..15b39f2df891f 100644 --- a/media/jni/soundpool/StreamManager.h +++ b/media/jni/soundpool/StreamManager.h @@ -52,6 +52,12 @@ public: JavaThread(JavaThread &&) = delete; // uses "this" ptr, not moveable. + ~JavaThread() { + join(); // manually block until the future is ready as std::future + // destructor doesn't block unless it comes from std::async + // and it is the last reference to shared state. + } + void join() const { mFuture.wait(); } @@ -64,8 +70,9 @@ private: static int staticFunction(void *data) { JavaThread *jt = static_cast(data); jt->mF(); - jt->mIsClosed = true; jt->mPromise.set_value(); + jt->mIsClosed = true; // publicly inform that we are closed + // after we have accessed all variables. return 0; }