void ServiceControl(int offset, const std::string& operation, int ranking) { if (0 <= offset && offset <= 3) { if (operation == "register") { if (!servregs[offset]) { std::stringstream servicename; servicename << SERVICE << offset; InterfaceMap ifm; ifm.insert(std::make_pair(servicename.str(), static_cast<void*>(this))); ServiceProperties props; props.insert(std::make_pair(ServiceConstants::SERVICE_RANKING(), Any(ranking))); servregs[offset] = mc->RegisterService(ifm, props); } } if (operation == "unregister") { if (servregs[offset]) { ServiceRegistrationU sr1 = servregs[offset]; sr1.Unregister(); servregs[offset] = 0; } } } }
US_END_NAMESPACE void TestServiceFactoryModuleScope() { // Install and start test module H, a service factory and test that the methods // in that interface works. SharedLibrary target(LIB_PATH, "TestModuleH"); #ifdef US_BUILD_SHARED_LIBS try { target.Load(); } catch (const std::exception& e) { US_TEST_FAILED_MSG( << "Failed to load module, got exception: " << e.what()) } #endif Module* moduleH = ModuleRegistry::GetModule("TestModuleH"); US_TEST_CONDITION_REQUIRED(moduleH != 0, "Test for existing module TestModuleH") std::vector<ServiceReferenceU> registeredRefs = moduleH->GetRegisteredServices(); US_TEST_CONDITION_REQUIRED(registeredRefs.size() == 2, "# of registered services") US_TEST_CONDITION(registeredRefs[0].GetProperty(ServiceConstants::SERVICE_SCOPE()).ToString() == ServiceConstants::SCOPE_MODULE(), "service scope") US_TEST_CONDITION(registeredRefs[1].GetProperty(ServiceConstants::SERVICE_SCOPE()).ToString() == ServiceConstants::SCOPE_PROTOTYPE(), "service scope") ModuleContext* mc = GetModuleContext(); // Check that a service reference exist const ServiceReferenceU sr1 = mc->GetServiceReference("us::TestModuleH"); US_TEST_CONDITION_REQUIRED(sr1, "Service shall be present.") US_TEST_CONDITION(sr1.GetProperty(ServiceConstants::SERVICE_SCOPE()).ToString() == ServiceConstants::SCOPE_MODULE(), "service scope") InterfaceMap service = mc->GetService(sr1); US_TEST_CONDITION_REQUIRED(service.size() >= 1, "GetService()") InterfaceMap::const_iterator serviceIter = service.find("us::TestModuleH"); US_TEST_CONDITION_REQUIRED(serviceIter != service.end(), "GetService()") US_TEST_CONDITION_REQUIRED(serviceIter->second != nullptr, "GetService()") InterfaceMap service2 = mc->GetService(sr1); US_TEST_CONDITION(service == service2, "Same service pointer") std::vector<ServiceReferenceU> usedRefs = mc->GetModule()->GetServicesInUse(); US_TEST_CONDITION_REQUIRED(usedRefs.size() == 1, "services in use") US_TEST_CONDITION(usedRefs[0] == sr1, "service ref in use") InterfaceMap service3 = moduleH->GetModuleContext()->GetService(sr1); US_TEST_CONDITION(service != service3, "Different service pointer") US_TEST_CONDITION(moduleH->GetModuleContext()->UngetService(sr1), "UngetService()") US_TEST_CONDITION_REQUIRED(mc->UngetService(sr1) == false, "ungetService()") US_TEST_CONDITION_REQUIRED(mc->UngetService(sr1) == true, "ungetService()") target.Unload(); }
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; }
void* ServiceObjectsBase::GetService() const { if (!d->m_reference) { return nullptr; } InterfaceMap im = d->GetServiceInterfaceMap(); void* result = im.find(d->m_reference.GetInterfaceId())->second; if (result) { d->m_serviceInstances.insert(std::make_pair(result, im)); } return result; }
void* ServiceReferenceBasePrivate::GetService(Module* module) { void* s = nullptr; { 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) { const InterfaceMap im = GetServiceFromFactory(module, serviceFactory, true); s = im.find(interfaceId)->second; } else { s = registration->GetService(interfaceId); } } else { if (serviceFactory) { // return the already produced instance s = registration->moduleServiceInstance[module][interfaceId]; } else { s = registration->GetService(interfaceId); } } if (s) { registration->dependents[module] = count + 1; } } } 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; }
InterfaceMap genInterfaceMap() { InterfaceMap ifmap; struct ifaddrs *if_addrs = nullptr, *if_addr = nullptr; if (getifaddrs(&if_addrs) != 0 || if_addrs == nullptr) { return ifmap; } InterfaceMap::iterator it = ifmap.begin(); for (if_addr = if_addrs; if_addr != nullptr; if_addr = if_addr->ifa_next) { if (if_addr->ifa_addr != nullptr && if_addr->ifa_addr->sa_family == AF_LINK) { auto route_type = std::string(if_addr->ifa_name); auto sdl = (struct sockaddr_dl *)if_addr->ifa_addr; ifmap.insert(it, std::make_pair(sdl->sdl_index, route_type)); } } freeifaddrs(if_addrs); return ifmap; }
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; }
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); } }