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

Commit 15ad2470 authored by Zhijun He's avatar Zhijun He
Browse files

Camera: Fix deadlock in Camera3OutputStream

process capture request thread, process capture result and setParameter
binder threads can run into circular locking situation when acquiring
StreamingProcessor lock, Camera3Stream lock, and bufferQueue lock.
Releasing the Camera3Stream lock briefly in process capture request
thread getbuffer call can break this deadlock.

Bug: 11016037
Change-Id: If08d4b134c26be26039b1d5363759e60f911bad6
parent d5ed2263
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -92,7 +92,22 @@ status_t Camera3OutputStream::getBufferLocked(camera3_stream_buffer *buffer) {
    ANativeWindowBuffer* anb;
    int fenceFd;

    res = mConsumer->dequeueBuffer(mConsumer.get(), &anb, &fenceFd);
    /**
     * Release the lock briefly to avoid deadlock for below scenario:
     * Thread 1: StreamingProcessor::startStream -> Camera3Stream::isConfiguring().
     * This thread acquired StreamingProcessor lock and try to lock Camera3Stream lock.
     * Thread 2: Camera3Stream::returnBuffer->StreamingProcessor::onFrameAvailable().
     * This thread acquired Camera3Stream lock and bufferQueue lock, and try to lock
     * StreamingProcessor lock.
     * Thread 3: Camera3Stream::getBuffer(). This thread acquired Camera3Stream lock
     * and try to lock bufferQueue lock.
     * Then there is circular locking dependency.
     */
    sp<ANativeWindow> currentConsumer = mConsumer;
    mLock.unlock();

    res = currentConsumer->dequeueBuffer(currentConsumer.get(), &anb, &fenceFd);
    mLock.lock();
    if (res != OK) {
        ALOGE("%s: Stream %d: Can't dequeue next output buffer: %s (%d)",
                __FUNCTION__, mId, strerror(-res), res);