/// Retrieve an existing AsChainLink based on ODI token. // // If the returned link is_set(), caller MUST call release() when it // is finished with the link. AsChainLink AsChainTable::lookup(const std::string& token) { pthread_mutex_lock(&_lock); std::map<std::string, AsChainLink>::const_iterator it = _odi_token_map.find(token); if (it == _odi_token_map.end()) { pthread_mutex_unlock(&_lock); return AsChainLink(NULL, 0); } else { // Found the AsChainLink. Add a reference to the AsChain. const AsChainLink& as_chain_link = it->second; if (as_chain_link._as_chain->inc_ref()) { // Flag that the AS corresponding to the previous link in the chain has // effectively responded. as_chain_link._as_chain->_responsive[as_chain_link._index - 1] = true; pthread_mutex_unlock(&_lock); return as_chain_link; } else { // Failed to increment the count - AS chain must be in the process of // being destroyed. Pretend we didn't find it. // LCOV_EXCL_START - Can't hit this window condition in UT. pthread_mutex_unlock(&_lock); return AsChainLink(NULL, 0); // LCOV_EXCL_STOP } } }
/// Create the tokens for the given AsChain, and register them to /// point at the next step in each case. void AsChainTable::register_(AsChain* as_chain, std::vector<std::string>& tokens) { size_t len = as_chain->size() + 1; pthread_mutex_lock(&_lock); for (size_t i = 0; i < len; i++) { std::string token; Utils::create_random_token(TOKEN_LENGTH, token); tokens.push_back(token); _odi_token_map[token] = AsChainLink(as_chain, i); } pthread_mutex_unlock(&_lock); }
/// Retrieve an existing AsChainLink based on ODI token. // // If the returned link is_set(), caller MUST call release() when it // is finished with the link. AsChainLink AsChainTable::lookup(const std::string& token) { pthread_mutex_lock(&_lock); std::map<std::string, AsChainLink>::const_iterator it = _t2c_map.find(token); if (it == _t2c_map.end()) { pthread_mutex_unlock(&_lock); return AsChainLink(NULL, 0); } else { it->second._as_chain->inc_ref(); pthread_mutex_unlock(&_lock); return it->second; } }
/// Create a new AsChain and return a link pointing at the start of // it. Caller MUST eventually call release() when it is finished with the // AsChainLink. // // Ownership of `ifcs` passes to this object. AsChainLink AsChainLink::create_as_chain(AsChainTable* as_chain_table, const SessionCase& session_case, const std::string& served_user, bool is_registered, SAS::TrailId trail, Ifcs& ifcs, ACR* acr) { AsChain* as_chain = new AsChain(as_chain_table, session_case, served_user, is_registered, trail, ifcs, acr); return AsChainLink(as_chain, 0u); }
/// Create a new AsChain and return a link pointing at the start of // it. Caller MUST eventually call release() when it is finished with the // AsChainLink. // // Ownership of `ifcs` passes to this object. AsChainLink AsChainLink::create_as_chain(AsChainTable* as_chain_table, const SessionCase& session_case, const std::string& served_user, bool is_registered, SAS::TrailId trail, Ifcs& ifcs, ACR* acr, FIFCService* fifc_service, IFCConfiguration ifc_configuration) { AsChain* as_chain = new AsChain(as_chain_table, session_case, served_user, is_registered, trail, ifcs, acr, fifc_service, ifc_configuration); return AsChainLink(as_chain, 0u); }