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

Commit 0f1889ef authored by Igor Murashkin's avatar Igor Murashkin
Browse files

gui: Surface::dequeueBuffer no locker holds mutex while blocking in binder

- This also fixes a hang in the camera service when trying to shut down
  if the producer is infinitely blocked while trying to get a new buffer.

Bug: 13250382
Change-Id: I32ca82162bb8645b97dbe084e13e05ca05529a42
parent d6b4e78d
Loading
Loading
Loading
Loading
+26 −7
Original line number Diff line number Diff line
@@ -178,19 +178,38 @@ int Surface::setSwapInterval(int interval) {
int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
    ATRACE_CALL();
    ALOGV("Surface::dequeueBuffer");

    int reqW;
    int reqH;
    bool swapIntervalZero;
    uint32_t reqFormat;
    uint32_t reqUsage;

    {
        Mutex::Autolock lock(mMutex);

        reqW = mReqWidth ? mReqWidth : mUserWidth;
        reqH = mReqHeight ? mReqHeight : mUserHeight;

        swapIntervalZero = mSwapIntervalZero;
        reqFormat = mReqFormat;
        reqUsage = mReqUsage;
    } // Drop the lock so that we can still touch the Surface while blocking in IGBP::dequeueBuffer

    int buf = -1;
    int reqW = mReqWidth ? mReqWidth : mUserWidth;
    int reqH = mReqHeight ? mReqHeight : mUserHeight;
    sp<Fence> fence;
    status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, mSwapIntervalZero,
            reqW, reqH, mReqFormat, mReqUsage);
    status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, swapIntervalZero,
            reqW, reqH, reqFormat, reqUsage);

    if (result < 0) {
        ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer(%d, %d, %d, %d)"
             "failed: %d", mReqWidth, mReqHeight, mReqFormat, mReqUsage,
        ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer(%d, %d, %d, %d, %d)"
             "failed: %d", swapIntervalZero, reqW, reqH, reqFormat, reqUsage,
             result);
        return result;
    }

    Mutex::Autolock lock(mMutex);

    sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);

    // this should never happen