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

Commit 1fc25d29 authored by Pawin Vongmasa's avatar Pawin Vongmasa Committed by android-build-merger
Browse files

Merge "Codec2Client: Retry creation on failed transaction" into qt-qpr1-dev...

Merge "Codec2Client: Retry creation on failed transaction" into qt-qpr1-dev am: dac33eaf am: fc69989a
am: ec63eeb3

Change-Id: I15e0c822e6a6d46ef56c7ca9b86d513542636cd5
parents 77819b82 ec63eeb3
Loading
Loading
Loading
Loading
+78 −62
Original line number Diff line number Diff line
@@ -125,6 +125,9 @@ public:
        if (!mClient) {
            mClient = Codec2Client::_CreateFromIndex(mIndex);
        }
        CHECK(mClient) << "Failed to create Codec2Client to service \""
                       << GetServiceNames()[mIndex] << "\". (Index = "
                       << mIndex << ").";
        return mClient;
    }

@@ -832,6 +835,7 @@ std::shared_ptr<Codec2Client> Codec2Client::_CreateFromIndex(size_t index) {

c2_status_t Codec2Client::ForAllServices(
        const std::string &key,
        size_t numberOfAttempts,
        std::function<c2_status_t(const std::shared_ptr<Codec2Client>&)>
            predicate) {
    c2_status_t status = C2_NO_INIT;  // no IComponentStores present
@@ -860,20 +864,28 @@ c2_status_t Codec2Client::ForAllServices(

    for (size_t index : indices) {
        Cache& cache = Cache::List()[index];
        for (size_t tries = numberOfAttempts; tries > 0; --tries) {
            std::shared_ptr<Codec2Client> client{cache.getClient()};
        if (client) {
            status = predicate(client);
            if (status == C2_OK) {
                std::scoped_lock lock{key2IndexMutex};
                key2Index[key] = index; // update last known client index
                return C2_OK;
            }
            } else if (status == C2_TRANSACTION_FAILED) {
                LOG(WARNING) << "\"" << key << "\" failed for service \""
                             << client->getName()
                             << "\" due to transaction failure. "
                             << "(Service may have crashed.)"
                             << (tries > 1 ? " Retrying..." : "");
                cache.invalidate();
                continue;
            }
            if (wasMapped) {
            LOG(INFO) << "Could not find \"" << key << "\""
                         " in the last instance. Retrying...";
                LOG(INFO) << "\"" << key << "\" became invalid in service \""
                          << client->getName() << "\". Retrying...";
                wasMapped = false;
            cache.invalidate();
            }
            break;
        }
    }
    return status; // return the last status from a valid client
@@ -885,10 +897,12 @@ std::shared_ptr<Codec2Client::Component>
        const std::shared_ptr<Listener>& listener,
        std::shared_ptr<Codec2Client>* owner,
        size_t numberOfAttempts) {
    while (true) {
    std::string key{"create:"};
    key.append(componentName);
    std::shared_ptr<Component> component;
    c2_status_t status = ForAllServices(
                componentName,
            key,
            numberOfAttempts,
            [owner, &component, componentName, &listener](
                    const std::shared_ptr<Codec2Client> &client)
                        -> c2_status_t {
@@ -908,23 +922,25 @@ std::shared_ptr<Codec2Client::Component>
                }
                return status;
            });
        if (numberOfAttempts > 0 && status == C2_TRANSACTION_FAILED) {
            --numberOfAttempts;
            continue;
    if (status != C2_OK) {
        LOG(DEBUG) << "Failed to create component \"" << componentName
                   << "\" from all known services. "
                      "Last returned status = " << status << ".";
    }
    return component;
}
}

std::shared_ptr<Codec2Client::Interface>
        Codec2Client::CreateInterfaceByName(
        const char* interfaceName,
        std::shared_ptr<Codec2Client>* owner,
        size_t numberOfAttempts) {
    while (true) {
    std::string key{"create:"};
    key.append(interfaceName);
    std::shared_ptr<Interface> interface;
    c2_status_t status = ForAllServices(
                interfaceName,
            key,
            numberOfAttempts,
            [owner, &interface, interfaceName](
                    const std::shared_ptr<Codec2Client> &client)
                        -> c2_status_t {
@@ -943,13 +959,13 @@ std::shared_ptr<Codec2Client::Interface>
                }
                return status;
            });
        if (numberOfAttempts > 0 && status == C2_TRANSACTION_FAILED) {
            --numberOfAttempts;
            continue;
    if (status != C2_OK) {
        LOG(DEBUG) << "Failed to create interface \"" << interfaceName
                   << "\" from all known services. "
                      "Last returned status = " << status << ".";
    }
    return interface;
}
}

std::vector<C2Component::Traits> const& Codec2Client::ListComponents() {
    static std::vector<C2Component::Traits> sList{[]() {
+17 −3
Original line number Diff line number Diff line
@@ -208,11 +208,25 @@ struct Codec2Client : public Codec2ConfigurableClient {
protected:
    sp<Base> mBase;

    // Finds the first store where the predicate returns OK, and returns the last
    // predicate result. Uses key to remember the last store found, and if cached,
    // it tries that store before trying all stores (one retry).
    // Finds the first store where the predicate returns C2_OK and returns the
    // last predicate result. The predicate will be tried on all stores. The
    // function will return C2_OK the first time the predicate returns C2_OK,
    // or it will return the value from the last time that predicate is tried.
    // (The latter case corresponds to a failure on every store.) The order of
    // the stores to try is the same as the return value of GetServiceNames().
    //
    // key is used to remember the last store with which the predicate last
    // succeeded. If the last successful store is cached, it will be tried
    // first before all the stores are tried. Note that the last successful
    // store will be tried twice---first before all the stores, and another time
    // with all the stores.
    //
    // If an attempt to evaluate the predicate results in a transaction failure,
    // repeated attempts will be made until the predicate returns without a
    // transaction failure or numberOfAttempts attempts have been made.
    static c2_status_t ForAllServices(
            const std::string& key,
            size_t numberOfAttempts,
            std::function<c2_status_t(std::shared_ptr<Codec2Client> const&)>
                predicate);