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

Commit 32ab3d67 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "C2HIDL: handle unregistered death notification" into main

parents 9299b83b 7fed726f
Loading
Loading
Loading
Loading
+50 −0
Original line number Diff line number Diff line
/*
 * Copyright 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <C2BqBufferPriv.h>
#include <C2PlatformSupport.h>

namespace android {

// filter fn from component's blockpool container to bqpool conatainer
static inline bool BqPoolFilterFn(
        std::pair<const uint64_t, std::shared_ptr<C2BlockPool>> pool) {
    return (pool.second->getAllocatorId() == C2PlatformAllocatorStore::BUFFERQUEUE);
}

// convert fn from component's blockpool container to bqpool container
static inline std::shared_ptr<C2BufferQueueBlockPool> BqPoolConvertFn(
        std::pair<const uint64_t, std::shared_ptr<C2BlockPool>> pool) {
    return std::static_pointer_cast<C2BufferQueueBlockPool>(pool.second);
}

// This is similar to std::transform excpet there is \pred functor parameter.
// The elements with \pred function value \true only will be transformed and
// added to the dest container. (For portability std::ranges are not used.)
template <class InputIt, class OutputIt, class Pred, class Fct>
void transform_if(InputIt first, InputIt last, OutputIt dest, Pred pred, Fct transform)
{
   while (first != last) {
      if (pred(*first)) {
         *dest++ = transform(*first);
      }
      ++first;
   }
}

}  // namespace android
+41 −7
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#define LOG_TAG "Codec2-Component"
#include <android-base/logging.h>

#include <codec2/common/BqPoolInvalidateHelper.h>
#include <codec2/hidl/1.0/Component.h>
#include <codec2/hidl/1.0/ComponentStore.h>
#include <codec2/hidl/1.0/InputBufferManager.h>
@@ -30,6 +31,7 @@
#include <utils/Timers.h>

#include <C2BqBufferPriv.h>
#include <C2BqPoolInvalidator.h>
#include <C2Debug.h>
#include <C2PlatformSupport.h>

@@ -270,16 +272,17 @@ c2_status_t Component::status() const {
}

void Component::onDeathReceived() {
    std::list<std::shared_ptr<C2BufferQueueBlockPool>> bqPools;
    {
        std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
        mClientDied = true;
        for (auto it = mBlockPools.begin(); it != mBlockPools.end(); ++it) {
            if (it->second->getAllocatorId() == C2PlatformAllocatorStore::BUFFERQUEUE) {
                std::shared_ptr<C2BufferQueueBlockPool> bqPool =
                        std::static_pointer_cast<C2BufferQueueBlockPool>(it->second);
                bqPool->invalidate();
            }
        transform_if(mBlockPools.begin(), mBlockPools.end(), std::back_inserter(bqPools),
                BqPoolFilterFn, BqPoolConvertFn);
    }
    if (!bqPools.empty()) {
        std::shared_ptr<C2BqPoolInvalidateItem> bqInvalidateItem =
                std::make_shared<C2BqPoolInvalidateItem>(std::move(bqPools));
        bqInvalidateItem->invalidate();
    }
    release();
}
@@ -549,7 +552,26 @@ Return<Status> Component::reset() {
}

Return<Status> Component::release() {
    std::list<std::shared_ptr<C2BufferQueueBlockPool>> bqPools;
    {
        std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
        if (!mClientDied) {
            transform_if(mBlockPools.begin(), mBlockPools.end(), std::back_inserter(bqPools),
                     BqPoolFilterFn, BqPoolConvertFn);
        }
    }
    std::shared_ptr<C2BqPoolInvalidateItem> bqInvalidateItem;
    if (!bqPools.empty()) {
        // handling rare cases of process death just after release() called.
        bqInvalidateItem = std::make_shared<C2BqPoolInvalidateItem>(std::move(bqPools));
        C2BqPoolInvalidator::getInstance().queue(bqInvalidateItem);
    }
    Status status = static_cast<Status>(mComponent->release());
    if (bqInvalidateItem) {
        // If release is not blocked,
        // skip invalidation and finish ASAP.
        bqInvalidateItem->skip();
    }
    {
        std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
        mBlockPools.clear();
@@ -637,6 +659,18 @@ void Component::initListener(const sp<Component>& self) {
}

Component::~Component() {
    std::list<std::shared_ptr<C2BufferQueueBlockPool>> bqPools;
    {
        std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
        transform_if(mBlockPools.begin(), mBlockPools.end(), std::back_inserter(bqPools),
                     BqPoolFilterFn, BqPoolConvertFn);
    }
    if (!bqPools.empty()) {
        LOG(ERROR) << "blockpools are not cleared yet at dtor";
        std::shared_ptr<C2BqPoolInvalidateItem> bqInvalidateItem =
                std::make_shared<C2BqPoolInvalidateItem>(std::move(bqPools));
        C2BqPoolInvalidator::getInstance().queue(bqInvalidateItem);
    }
    InputBufferManager::unregisterFrameData(mListener);
    mStore->reportComponentDeath(this);
}
+41 −7
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#define LOG_TAG "Codec2-Component@1.1"
#include <android-base/logging.h>

#include <codec2/common/BqPoolInvalidateHelper.h>
#include <codec2/hidl/1.1/Component.h>
#include <codec2/hidl/1.1/ComponentStore.h>
#include <codec2/hidl/1.1/InputBufferManager.h>
@@ -32,6 +33,7 @@
#include <codec2/common/MultiAccessUnitHelper.h>

#include <C2BqBufferPriv.h>
#include <C2BqPoolInvalidator.h>
#include <C2Debug.h>
#include <C2PlatformSupport.h>

@@ -274,16 +276,17 @@ c2_status_t Component::status() const {
}

void Component::onDeathReceived() {
    std::list<std::shared_ptr<C2BufferQueueBlockPool>> bqPools;
    {
        std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
        mClientDied = true;
        for (auto it = mBlockPools.begin(); it != mBlockPools.end(); ++it) {
            if (it->second->getAllocatorId() == C2PlatformAllocatorStore::BUFFERQUEUE) {
                std::shared_ptr<C2BufferQueueBlockPool> bqPool =
                        std::static_pointer_cast<C2BufferQueueBlockPool>(it->second);
                bqPool->invalidate();
            }
        transform_if(mBlockPools.begin(), mBlockPools.end(), std::back_inserter(bqPools),
                BqPoolFilterFn, BqPoolConvertFn);
    }
    if (!bqPools.empty()) {
        std::shared_ptr<C2BqPoolInvalidateItem> bqInvalidateItem =
                std::make_shared<C2BqPoolInvalidateItem>(std::move(bqPools));
        bqInvalidateItem->invalidate();
    }
    release();
}
@@ -555,7 +558,26 @@ Return<Status> Component::reset() {
}

Return<Status> Component::release() {
    std::list<std::shared_ptr<C2BufferQueueBlockPool>> bqPools;
    {
        std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
        if (!mClientDied) {
            transform_if(mBlockPools.begin(), mBlockPools.end(), std::back_inserter(bqPools),
                    BqPoolFilterFn, BqPoolConvertFn);
        }
    }
    std::shared_ptr<C2BqPoolInvalidateItem> bqInvalidateItem;
    if (!bqPools.empty()) {
        // handling rare cases of process death just after release() called.
        bqInvalidateItem = std::make_shared<C2BqPoolInvalidateItem>(std::move(bqPools));
        C2BqPoolInvalidator::getInstance().queue(bqInvalidateItem);
    }
    Status status = static_cast<Status>(mComponent->release());
    if (bqInvalidateItem) {
        // If release is not blocked,
        // skip invalidation and finish ASAP.
        bqInvalidateItem->skip();
    }
    {
        std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
        mBlockPools.clear();
@@ -649,6 +671,18 @@ void Component::initListener(const sp<Component>& self) {
}

Component::~Component() {
    std::list<std::shared_ptr<C2BufferQueueBlockPool>> bqPools;
    {
        std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
        transform_if(mBlockPools.begin(), mBlockPools.end(), std::back_inserter(bqPools),
                BqPoolFilterFn, BqPoolConvertFn);
    }
    if (!bqPools.empty()) {
        LOG(ERROR) << "blockpools are not cleared yet at dtor";
        std::shared_ptr<C2BqPoolInvalidateItem> bqInvalidateItem =
                std::make_shared<C2BqPoolInvalidateItem>(std::move(bqPools));
        C2BqPoolInvalidator::getInstance().queue(bqInvalidateItem);
    }
    InputBufferManager::unregisterFrameData(mListener);
    mStore->reportComponentDeath(this);
}
+41 −7
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#define LOG_TAG "Codec2-Component@1.2"
#include <android-base/logging.h>

#include <codec2/common/BqPoolInvalidateHelper.h>
#include <codec2/hidl/1.2/Component.h>
#include <codec2/hidl/1.2/ComponentStore.h>
#include <codec2/hidl/1.2/InputBufferManager.h>
@@ -30,6 +31,7 @@
#include <utils/Timers.h>

#include <C2BqBufferPriv.h>
#include <C2BqPoolInvalidator.h>
#include <C2Debug.h>
#include <C2PlatformSupport.h>

@@ -272,16 +274,17 @@ c2_status_t Component::status() const {
}

void Component::onDeathReceived() {
    std::list<std::shared_ptr<C2BufferQueueBlockPool>> bqPools;
    {
        std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
        mClientDied = true;
        for (auto it = mBlockPools.begin(); it != mBlockPools.end(); ++it) {
            if (it->second->getAllocatorId() == C2PlatformAllocatorStore::BUFFERQUEUE) {
                std::shared_ptr<C2BufferQueueBlockPool> bqPool =
                        std::static_pointer_cast<C2BufferQueueBlockPool>(it->second);
                bqPool->invalidate();
            }
        transform_if(mBlockPools.begin(), mBlockPools.end(), std::back_inserter(bqPools),
                BqPoolFilterFn, BqPoolConvertFn);
    }
    if (!bqPools.empty()) {
        std::shared_ptr<C2BqPoolInvalidateItem> bqInvalidateItem =
                std::make_shared<C2BqPoolInvalidateItem>(std::move(bqPools));
        bqInvalidateItem->invalidate();
    }
    release();
}
@@ -551,7 +554,26 @@ Return<Status> Component::reset() {
}

Return<Status> Component::release() {
    std::list<std::shared_ptr<C2BufferQueueBlockPool>> bqPools;
    {
        std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
        if (!mClientDied) {
            transform_if(mBlockPools.begin(), mBlockPools.end(), std::back_inserter(bqPools),
                    BqPoolFilterFn, BqPoolConvertFn);
        }
    }
    std::shared_ptr<C2BqPoolInvalidateItem> bqInvalidateItem;
    if (!bqPools.empty()) {
        // handling rare cases of process death just after release() called.
        bqInvalidateItem = std::make_shared<C2BqPoolInvalidateItem>(std::move(bqPools));
        C2BqPoolInvalidator::getInstance().queue(bqInvalidateItem);
    }
    Status status = static_cast<Status>(mComponent->release());
    if (bqInvalidateItem) {
        // If release is not blocked,
        // skip invalidation and finish ASAP.
        bqInvalidateItem->skip();
    }
    {
        std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
        mBlockPools.clear();
@@ -676,6 +698,18 @@ void Component::initListener(const sp<Component>& self) {
}

Component::~Component() {
    std::list<std::shared_ptr<C2BufferQueueBlockPool>> bqPools;
    {
        std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
        transform_if(mBlockPools.begin(), mBlockPools.end(), std::back_inserter(bqPools),
                BqPoolFilterFn, BqPoolConvertFn);
    }
    if (!bqPools.empty()) {
        LOG(ERROR) << "blockpools are not cleared yet at dtor";
        std::shared_ptr<C2BqPoolInvalidateItem> bqInvalidateItem =
                std::make_shared<C2BqPoolInvalidateItem>(std::move(bqPools));
        C2BqPoolInvalidator::getInstance().queue(bqInvalidateItem);
    }
    InputBufferManager::unregisterFrameData(mListener);
    mStore->reportComponentDeath(this);
}
+2 −1
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ cc_library {
        "C2PlatformStorePluginLoader.cpp",
        "C2Store.cpp",
        "platform/C2BqBuffer.cpp",
        "platform/C2BqPoolInvalidator.cpp",
        "platform/C2SurfaceSyncObj.cpp",
        "platform/C2IgbaBuffer.cpp",
        "types.cpp",
Loading