Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19cd146a authored by Vishnu Nair's avatar Vishnu Nair
Browse files

BlastBufferQueue: Fix async worker deadlock

The async onBufferReleased callback can trigger another
onBufferReleased which will end up deadlocking the
async worker thread. Fix this by executing the callbacks
outside the lock.

Test: atest android.media.cts.MediaSyncTest#testPlaybackRateDouble --rerun-util-failure 100
Bug: 201604213
Change-Id: I40d163c3644c6a0128936cf41e8bf8969766d9da
Merged-In: I40d163c3644c6a0128936cf41e8bf8969766d9da
parent 41561142
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -731,14 +731,26 @@ private:
        std::unique_lock<std::mutex> lock(mMutex);
        while (!mDone) {
            while (!mRunnables.empty()) {
                std::function<void()> runnable = mRunnables.front();
                mRunnables.pop_front();
                runnable();
                std::deque<std::function<void()>> runnables = std::move(mRunnables);
                mRunnables.clear();
                lock.unlock();
                // Run outside the lock since the runnable might trigger another
                // post to the async worker.
                execute(runnables);
                lock.lock();
            }
            mCv.wait(lock);
        }
    }

    void execute(std::deque<std::function<void()>>& runnables) {
        while (!runnables.empty()) {
            std::function<void()> runnable = runnables.front();
            runnables.pop_front();
            runnable();
        }
    }

public:
    AsyncWorker() : Singleton<AsyncWorker>() { mThread = std::thread(&AsyncWorker::run, this); }