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;
}
Beispiel #2
0
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;
}
Beispiel #5
0
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);
  }
}