DO NOT MERGE - Merge QQ1A.200205.002 into master

Bug: 147428392
Change-Id: Idd35f9e9df48ed9909b338325dd15b670da492e7
gugelfrei
Xin Li 4 years ago
commit 9bc61dc953

@ -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,23 +864,31 @@ c2_status_t Codec2Client::ForAllServices(
for (size_t index : indices) {
Cache& cache = Cache::List()[index];
std::shared_ptr<Codec2Client> client{cache.getClient()};
if (client) {
for (size_t tries = numberOfAttempts; tries > 0; --tries) {
std::shared_ptr<Codec2Client> client{cache.getClient()};
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...";
wasMapped = false;
cache.invalidate();
if (wasMapped) {
LOG(INFO) << "\"" << key << "\" became invalid in service \""
<< client->getName() << "\". Retrying...";
wasMapped = false;
}
break;
}
}
return status; // return the last status from a valid client
return status; // return the last status from a valid client
}
std::shared_ptr<Codec2Client::Component>
@ -885,35 +897,37 @@ std::shared_ptr<Codec2Client::Component>
const std::shared_ptr<Listener>& listener,
std::shared_ptr<Codec2Client>* owner,
size_t numberOfAttempts) {
while (true) {
std::shared_ptr<Component> component;
c2_status_t status = ForAllServices(
componentName,
[owner, &component, componentName, &listener](
const std::shared_ptr<Codec2Client> &client)
-> c2_status_t {
c2_status_t status = client->createComponent(componentName,
listener,
&component);
if (status == C2_OK) {
if (owner) {
*owner = client;
}
} else if (status != C2_NOT_FOUND) {
LOG(DEBUG) << "IComponentStore("
<< client->getServiceName()
<< ")::createComponent(\"" << componentName
<< "\") returned status = "
<< status << ".";
std::string key{"create:"};
key.append(componentName);
std::shared_ptr<Component> component;
c2_status_t status = ForAllServices(
key,
numberOfAttempts,
[owner, &component, componentName, &listener](
const std::shared_ptr<Codec2Client> &client)
-> c2_status_t {
c2_status_t status = client->createComponent(componentName,
listener,
&component);
if (status == C2_OK) {
if (owner) {
*owner = client;
}
return status;
});
if (numberOfAttempts > 0 && status == C2_TRANSACTION_FAILED) {
--numberOfAttempts;
continue;
}
return component;
} else if (status != C2_NOT_FOUND) {
LOG(DEBUG) << "IComponentStore("
<< client->getServiceName()
<< ")::createComponent(\"" << componentName
<< "\") returned status = "
<< status << ".";
}
return status;
});
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>
@ -921,34 +935,36 @@ std::shared_ptr<Codec2Client::Interface>
const char* interfaceName,
std::shared_ptr<Codec2Client>* owner,
size_t numberOfAttempts) {
while (true) {
std::shared_ptr<Interface> interface;
c2_status_t status = ForAllServices(
interfaceName,
[owner, &interface, interfaceName](
const std::shared_ptr<Codec2Client> &client)
-> c2_status_t {
c2_status_t status = client->createInterface(interfaceName,
&interface);
if (status == C2_OK) {
if (owner) {
*owner = client;
}
} else if (status != C2_NOT_FOUND) {
LOG(DEBUG) << "IComponentStore("
<< client->getServiceName()
<< ")::createInterface(\"" << interfaceName
<< "\") returned status = "
<< status << ".";
std::string key{"create:"};
key.append(interfaceName);
std::shared_ptr<Interface> interface;
c2_status_t status = ForAllServices(
key,
numberOfAttempts,
[owner, &interface, interfaceName](
const std::shared_ptr<Codec2Client> &client)
-> c2_status_t {
c2_status_t status = client->createInterface(interfaceName,
&interface);
if (status == C2_OK) {
if (owner) {
*owner = client;
}
return status;
});
if (numberOfAttempts > 0 && status == C2_TRANSACTION_FAILED) {
--numberOfAttempts;
continue;
}
return interface;
} else if (status != C2_NOT_FOUND) {
LOG(DEBUG) << "IComponentStore("
<< client->getServiceName()
<< ")::createInterface(\"" << interfaceName
<< "\") returned status = "
<< status << ".";
}
return status;
});
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() {

@ -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);

Loading…
Cancel
Save