Beispiel #1
0
void ServiceHooks::FilterServiceReferences(ModuleContext* mc, const std::string& service,
                                           const std::string& filter, std::vector<ServiceReferenceBase>& refs)
{
  std::vector<ServiceRegistrationBase> srl;
  coreCtx->services.Get_unlocked(us_service_interface_iid<ServiceFindHook>(), srl);
  if (!srl.empty())
  {
    ShrinkableVector<ServiceReferenceBase> filtered(refs);

    std::sort(srl.begin(), srl.end());
    for (std::vector<ServiceRegistrationBase>::reverse_iterator fhrIter = srl.rbegin(), fhrEnd = srl.rend();
         fhrIter != fhrEnd; ++fhrIter)
    {
      ServiceReference<ServiceFindHook> sr = fhrIter->GetReference();
      ServiceFindHook* const fh = reinterpret_cast<ServiceFindHook*>(sr.d->GetService(GetModuleContext()->GetModule()));
      if (fh != NULL)
      {
        try
        {
          fh->Find(mc, service, filter, filtered);
        }
        catch (const std::exception& e)
        {
          US_WARN << "Failed to call find hook  #" << sr.GetProperty(ServiceConstants::SERVICE_ID()).ToString()
                  << ": " << e.what();
        }
        catch (...)
        {
          US_WARN << "Failed to call find hook  #" << sr.GetProperty(ServiceConstants::SERVICE_ID()).ToString()
                  << ": unknown exception type";
        }
      }
    }
  }
}
Beispiel #2
0
void ModuleHooks::FilterModules(const ModuleContext* mc, std::vector<Module*>& modules) const
{
  std::vector<ServiceRegistrationBase> srl;
  coreCtx->services.Get(us_service_interface_iid<ModuleFindHook>(), srl);
  ShrinkableVector<Module*> filtered(modules);

  std::sort(srl.begin(), srl.end());
  for (std::vector<ServiceRegistrationBase>::reverse_iterator srBaseIter = srl.rbegin(), srBaseEnd = srl.rend();
       srBaseIter != srBaseEnd; ++srBaseIter)
  {
    ServiceReference<ModuleFindHook> sr = srBaseIter->GetReference();
    ModuleFindHook* const fh = reinterpret_cast<ModuleFindHook*>(sr.d->GetService(GetModuleContext()->GetModule()));
    if (fh != nullptr)
    {
      try
      {
        fh->Find(mc, filtered);
      }
      catch (const std::exception& e)
      {
        US_WARN << "Failed to call Module FindHook  #" << sr.GetProperty(ServiceConstants::SERVICE_ID()).ToString()
                << ": " << e.what();
      }
      catch (...)
      {
        US_WARN << "Failed to call Module FindHook  #" << sr.GetProperty(ServiceConstants::SERVICE_ID()).ToString()
                << ": unknown exception type";
      }
    }
  }
}
Beispiel #3
0
void ServiceHooks::FilterServiceEventReceivers(const ServiceEvent& evt,
                                               ServiceListeners::ServiceListenerEntries& receivers)
{
  std::vector<ServiceRegistrationBase> eventListenerHooks;
  coreCtx->services.Get_unlocked(us_service_interface_iid<ServiceEventListenerHook>(), eventListenerHooks);
  if (!eventListenerHooks.empty())
  {
    std::sort(eventListenerHooks.begin(), eventListenerHooks.end());
    std::map<ModuleContext*, std::vector<ServiceListenerHook::ListenerInfo> > listeners;
    for (ServiceListeners::ServiceListenerEntries::iterator sleIter = receivers.begin(),
         sleEnd = receivers.end(); sleIter != sleEnd; ++sleIter)
    {
      listeners[sleIter->GetModuleContext()].push_back(*sleIter);
    }

    std::map<ModuleContext*, ShrinkableVector<ServiceListenerHook::ListenerInfo> > shrinkableListeners;
    for (std::map<ModuleContext*, std::vector<ServiceListenerHook::ListenerInfo> >::iterator iter = listeners.begin(),
         iterEnd = listeners.end(); iter != iterEnd; ++iter)
    {
      shrinkableListeners.insert(std::make_pair(iter->first, ShrinkableVector<ServiceListenerHook::ListenerInfo>(iter->second)));
    }

    ShrinkableMap<ModuleContext*, ShrinkableVector<ServiceListenerHook::ListenerInfo> > filtered(shrinkableListeners);

    for(std::vector<ServiceRegistrationBase>::reverse_iterator sriIter = eventListenerHooks.rbegin(),
        sriEnd = eventListenerHooks.rend(); sriIter != sriEnd; ++sriIter)
    {
      ServiceReference<ServiceEventListenerHook> sr = sriIter->GetReference();
      ServiceEventListenerHook* elh = reinterpret_cast<ServiceEventListenerHook*>(sr.d->GetService(GetModuleContext()->GetModule()));
      if(elh != NULL)
      {
        try
        {
          elh->Event(evt, filtered);
        }
        catch(const std::exception& e)
        {
          US_WARN << "Failed to call event hook  #" << sr.GetProperty(ServiceConstants::SERVICE_ID()).ToString()
                  << ": " << e.what();
        }
        catch(...)
        {
          US_WARN << "Failed to call event hook  #" << sr.GetProperty(ServiceConstants::SERVICE_ID()).ToString()
                  << ": unknown exception type";
        }
      }
    }
    receivers.clear();
    for(std::map<ModuleContext*, std::vector<ServiceListenerHook::ListenerInfo> >::iterator iter = listeners.begin(),
        iterEnd = listeners.end(); iter != iterEnd; ++iter)
    {
      receivers.insert(iter->second.begin(), iter->second.end());
    }
  }
}
Beispiel #4
0
void BundleHooks::FilterBundles(const BundleContext& context,
                                std::vector<Bundle>& bundles) const
{
  std::vector<ServiceRegistrationBase> srl;
  coreCtx->services.Get(us_service_interface_iid<BundleFindHook>(), srl);
  ShrinkableVector<Bundle> filtered(bundles);

  auto selfBundle = GetBundleContext().GetBundle();
  std::sort(srl.begin(), srl.end());
  for (auto srBaseIter = srl.rbegin(), srBaseEnd = srl.rend();
       srBaseIter != srBaseEnd;
       ++srBaseIter) {
    ServiceReference<BundleFindHook> sr = srBaseIter->GetReference();
    std::shared_ptr<BundleFindHook> fh =
      std::static_pointer_cast<BundleFindHook>(
        sr.d.load()->GetService(GetPrivate(selfBundle).get()));
    if (fh) {
      try {
        fh->Find(context, filtered);
      } catch (...) {
        std::string message("Failed to call Bundle FindHook  # " +
                            sr.GetProperty(Constants::SERVICE_ID).ToString());
        coreCtx->listeners.SendFrameworkEvent(
          FrameworkEvent(FrameworkEvent::Type::FRAMEWORK_WARNING,
                         selfBundle,
                         message,
                         std::current_exception()));
      }
    }
  }
}
void TestServiceFactoryPrototypeScope()
{

  // 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())
  }

  Module* moduleH = ModuleRegistry::GetModule("TestModuleH");
  US_TEST_CONDITION_REQUIRED(moduleH != 0, "Test for existing module TestModuleH")
#endif

  ModuleContext* mc = GetModuleContext();
  // Check that a service reference exist
  const ServiceReference<TestModuleH2> sr1 = mc->GetServiceReference<TestModuleH2>();
  US_TEST_CONDITION_REQUIRED(sr1, "Service shall be present.")
  US_TEST_CONDITION(sr1.GetProperty(ServiceConstants::SERVICE_SCOPE()).ToString() == ServiceConstants::SCOPE_PROTOTYPE(), "service scope")

  ServiceObjects<TestModuleH2> svcObjects = mc->GetServiceObjects(sr1);
  TestModuleH2* prototypeServiceH2 = svcObjects.GetService();

  const ServiceReferenceU sr1void = mc->GetServiceReference(us_service_interface_iid<TestModuleH2>());
  ServiceObjects<void> svcObjectsVoid = mc->GetServiceObjects(sr1void);
  InterfaceMap prototypeServiceH2Void = svcObjectsVoid.GetService();
  US_TEST_CONDITION_REQUIRED(prototypeServiceH2Void.find(us_service_interface_iid<TestModuleH2>()) != prototypeServiceH2Void.end(),
                             "ServiceObjects<void>::GetService()")

#ifdef US_BUILD_SHARED_LIBS
  // There should be only one service in use
  US_TEST_CONDITION_REQUIRED(mc->GetModule()->GetServicesInUse().size() == 1, "services in use")
#endif

  TestModuleH2* moduleScopeService = mc->GetService(sr1);
  US_TEST_CONDITION_REQUIRED(moduleScopeService && moduleScopeService != prototypeServiceH2, "GetService()")

  US_TEST_CONDITION_REQUIRED(prototypeServiceH2 != prototypeServiceH2Void.find(us_service_interface_iid<TestModuleH2>())->second,
                             "GetService()")

  svcObjectsVoid.UngetService(prototypeServiceH2Void);

  TestModuleH2* moduleScopeService2 = mc->GetService(sr1);
  US_TEST_CONDITION(moduleScopeService == moduleScopeService2, "Same service pointer")

#ifdef US_BUILD_SHARED_LIBS
  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")
#endif

  std::string filter = "(" + ServiceConstants::SERVICE_ID() + "=" + sr1.GetProperty(ServiceConstants::SERVICE_ID()).ToString() + ")";
  const ServiceReference<TestModuleH> sr2 = mc->GetServiceReferences<TestModuleH>(filter).front();
  US_TEST_CONDITION_REQUIRED(sr2, "Service shall be present.")
  US_TEST_CONDITION(sr2.GetProperty(ServiceConstants::SERVICE_SCOPE()).ToString() == ServiceConstants::SCOPE_PROTOTYPE(), "service scope")
  US_TEST_CONDITION(any_cast<long>(sr2.GetProperty(ServiceConstants::SERVICE_ID())) == any_cast<long>(sr1.GetProperty(ServiceConstants::SERVICE_ID())), "same service id")

  try
  {
    svcObjects.UngetService(moduleScopeService2);
    US_TEST_FAILED_MSG(<< "std::invalid_argument exception expected")
  }
  catch (const std::invalid_argument&)
  {
    // this is expected
  }

#ifdef US_BUILD_SHARED_LIBS
  // There should still be only one service in use
  usedRefs = mc->GetModule()->GetServicesInUse();
  US_TEST_CONDITION_REQUIRED(usedRefs.size() == 1, "services in use")
#endif

  ServiceObjects<TestModuleH2> svcObjects2 = svcObjects;
  ServiceObjects<TestModuleH2> svcObjects3 = mc->GetServiceObjects(sr1);
  try
  {
    svcObjects3.UngetService(prototypeServiceH2);
    US_TEST_FAILED_MSG(<< "std::invalid_argument exception expected")
  }
  catch (const std::invalid_argument&)
  {
    // this is expected
  }

  svcObjects2.UngetService(prototypeServiceH2);
  prototypeServiceH2 = svcObjects2.GetService();
  TestModuleH2* prototypeServiceH2_2 = svcObjects3.GetService();

  US_TEST_CONDITION_REQUIRED(prototypeServiceH2_2 && prototypeServiceH2_2 != prototypeServiceH2, "prototype service")

  svcObjects2.UngetService(prototypeServiceH2);
  svcObjects3.UngetService(prototypeServiceH2_2);
  US_TEST_CONDITION_REQUIRED(mc->UngetService(sr1) == false, "ungetService()")
  US_TEST_CONDITION_REQUIRED(mc->UngetService(sr1) == true, "ungetService()")

  target.Unload();
}
Beispiel #6
0
void ModuleHooks::FilterModuleEventReceivers(const ModuleEvent& evt,
                                             ServiceListeners::ModuleListenerMap& moduleListeners)
{
  std::vector<ServiceRegistrationBase> eventHooks;
  coreCtx->services.Get(us_service_interface_iid<ModuleEventHook>(), eventHooks);

  {
    MutexLock lock(coreCtx->listeners.moduleListenerMapMutex);
    moduleListeners = coreCtx->listeners.moduleListenerMap;
  }

  if(!eventHooks.empty())
  {
    std::vector<ModuleContext*> moduleContexts;
    for (ServiceListeners::ModuleListenerMap::iterator le = moduleListeners.begin(),
         leEnd = moduleListeners.end(); le != leEnd; ++le)
    {
      moduleContexts.push_back(le->first);
    }
    std::sort(moduleContexts.begin(), moduleContexts.end());
    moduleContexts.erase(std::unique(moduleContexts.begin(), moduleContexts.end()), moduleContexts.end());

    const std::size_t unfilteredSize = moduleContexts.size();
    ShrinkableVector<ModuleContext*> filtered(moduleContexts);

    std::sort(eventHooks.begin(), eventHooks.end());
    for (std::vector<ServiceRegistrationBase>::reverse_iterator iter = eventHooks.rbegin(),
         iterEnd = eventHooks.rend(); iter != iterEnd; ++iter)
    {
      ServiceReference<ModuleEventHook> sr;
      try
      {
        sr = iter->GetReference();
      }
      catch (const std::logic_error& e)
      {
        US_WARN << "Failed to get event hook service reference: " << e.what();
        continue;
      }

      ModuleEventHook* eh = reinterpret_cast<ModuleEventHook*>(sr.d->GetService(GetModuleContext()->GetModule()));
      if (eh != nullptr)
      {
        try
        {
          eh->Event(evt, filtered);
        }
        catch (const std::exception& e)
        {
          US_WARN << "Failed to call Module EventHook #" << sr.GetProperty(ServiceConstants::SERVICE_ID()).ToString()
                  << ": " << e.what();
        }
        catch (...)
        {
          US_WARN << "Failed to call Module EventHook #" << sr.GetProperty(ServiceConstants::SERVICE_ID()).ToString()
                  << ": unknown exception type";
        }
      }
    }

    if (unfilteredSize != moduleContexts.size())
    {
      for (ServiceListeners::ModuleListenerMap::iterator le = moduleListeners.begin();
           le != moduleListeners.end();)
      {
        if(std::find(moduleContexts.begin(), moduleContexts.end(), le->first) == moduleContexts.end())
        {
          moduleListeners.erase(le++);
        }
        else
        {
          ++le;
        }
      }
    }
  }
}
Beispiel #7
0
void BundleHooks::FilterBundleEventReceivers(
  const BundleEvent& evt,
  ServiceListeners::BundleListenerMap& bundleListeners)
{
  std::vector<ServiceRegistrationBase> eventHooks;
  coreCtx->services.Get(us_service_interface_iid<BundleEventHook>(),
                        eventHooks);

  {
    auto l = coreCtx->listeners.bundleListenerMap.Lock();
    US_UNUSED(l);
    bundleListeners = coreCtx->listeners.bundleListenerMap.value;
  }

  if (!eventHooks.empty()) {
    std::vector<BundleContext> bundleContexts;
    for (auto& le : bundleListeners) {
      bundleContexts.push_back(MakeBundleContext(le.first->shared_from_this()));
    }
    std::sort(bundleContexts.begin(), bundleContexts.end());
    bundleContexts.erase(
      std::unique(bundleContexts.begin(), bundleContexts.end()),
      bundleContexts.end());

    const std::size_t unfilteredSize = bundleContexts.size();
    ShrinkableVector<BundleContext> filtered(bundleContexts);

    std::sort(eventHooks.begin(), eventHooks.end());
    for (auto iter = eventHooks.rbegin(), iterEnd = eventHooks.rend();
         iter != iterEnd;
         ++iter) {
      ServiceReference<BundleEventHook> sr;
      try {
        sr = iter->GetReference();
      } catch (const std::logic_error&) {
        std::string message("Failed to get event hook service reference");
        coreCtx->listeners.SendFrameworkEvent(
          FrameworkEvent(FrameworkEvent::Type::FRAMEWORK_WARNING,
                         GetBundleContext().GetBundle(),
                         message,
                         std::current_exception()));
        continue;
      }

      std::shared_ptr<BundleEventHook> eh =
        std::static_pointer_cast<BundleEventHook>(sr.d.load()->GetService(
          GetPrivate(GetBundleContext().GetBundle()).get()));
      if (eh) {
        try {
          eh->Event(evt, filtered);
        } catch (...) {
          std::string message("Failed to call Bundle EventHook # " +
                              sr.GetProperty(Constants::SERVICE_ID).ToString());
          coreCtx->listeners.SendFrameworkEvent(
            FrameworkEvent(FrameworkEvent::Type::FRAMEWORK_WARNING,
                           GetBundleContext().GetBundle(),
                           message,
                           std::current_exception()));
        }
      }
    }

    if (unfilteredSize != bundleContexts.size()) {
      for (ServiceListeners::BundleListenerMap::iterator le =
             bundleListeners.begin();
           le != bundleListeners.end();) {
        if (std::find_if(bundleContexts.begin(),
                         bundleContexts.end(),
                         [&le](const BundleContext& bc) {
                           return GetPrivate(bc) == le->first;
                         }) == bundleContexts.end()) {
          bundleListeners.erase(le++);
        } else {
          ++le;
        }
      }
    }
  }
}