bool ServiceReferenceBasePrivate::UngetService(Module* module, bool checkRefCounter) { MutexLock lock(registration->propsLock); bool hadReferences = false; bool removeService = false; int count= registration->dependents[module]; if (count > 0) { hadReferences = true; } if(checkRefCounter) { if (count > 1) { registration->dependents[module] = count - 1; } else if(count == 1) { removeService = true; } } else { removeService = true; } if (removeService) { InterfaceMap sfi = registration->moduleServiceInstance[module]; registration->moduleServiceInstance.erase(module); if (!sfi.empty()) { try { ServiceFactory* sf = reinterpret_cast<ServiceFactory*>( registration->GetService("org.cppmicroservices.factory")); sf->UngetService(module, ServiceRegistrationBase(registration), sfi); } catch (const std::exception& /*e*/) { US_WARN << "ServiceFactory threw an exception"; } } registration->dependents.erase(module); } return hadReferences && removeService; }
InterfaceMap ServiceObjectsBase::GetServiceInterfaceMap() const { InterfaceMap result; if (!d->m_reference) { return result; } result = d->GetServiceInterfaceMap(); if (!result.empty()) { d->m_serviceInterfaceMaps.insert(result); } return result; }
InterfaceMap ServiceReferenceBasePrivate::GetServiceFromFactory(Module* module, ServiceFactory* factory, bool isModuleScope) { assert(factory && "Factory service pointer is nullptr"); InterfaceMap s; try { InterfaceMap smap = factory->GetService(module, ServiceRegistrationBase(registration)); if (smap.empty()) { US_WARN << "ServiceFactory produced null"; return smap; } const std::vector<std::string>& classes = ref_any_cast<std::vector<std::string> >(registration->properties.Value(ServiceConstants::OBJECTCLASS())); for (std::vector<std::string>::const_iterator i = classes.begin(); i != classes.end(); ++i) { if (smap.find(*i) == smap.end() && *i != "org.cppmicroservices.factory") { US_WARN << "ServiceFactory produced an object " "that did not implement: " << (*i); smap.clear(); return smap; } } s = smap; if (isModuleScope) { registration->moduleServiceInstance.insert(std::make_pair(module, smap)); } else { registration->prototypeServiceInstances[module].push_back(smap); } } catch (...) { US_WARN << "ServiceFactory threw an exception"; s.clear(); } return s; }
InterfaceMap ServiceReferenceBasePrivate::GetServiceInterfaceMap(Module* module) { InterfaceMap s; { MutexLock lock(registration->propsLock); if (registration->available) { ServiceFactory* serviceFactory = reinterpret_cast<ServiceFactory*>( registration->GetService("org.cppmicroservices.factory")); const int count = registration->dependents[module]; if (count == 0) { if (serviceFactory) { s = GetServiceFromFactory(module, serviceFactory, true); } else { s = registration->service; } } else { if (serviceFactory) { // return the already produced instance s = registration->moduleServiceInstance[module]; } else { s = registration->service; } } if (!s.empty()) { registration->dependents[module] = count + 1; } } } return s; }
void ServiceObjectsBase::UngetService(const InterfaceMap& interfaceMap) { if (interfaceMap.empty()) { return; } std::set<InterfaceMap>::iterator serviceIter = d->m_serviceInterfaceMaps.find(interfaceMap); if (serviceIter == d->m_serviceInterfaceMaps.end()) { throw std::invalid_argument("The provided service has not been retrieved via this ServiceObjects instance"); } if (!d->m_reference.d->UngetPrototypeService(d->m_context->GetModule(), interfaceMap)) { US_WARN << "Ungetting service unsuccessful"; } else { d->m_serviceInterfaceMaps.erase(serviceIter); } }