Пример #1
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 ServiceListeners::ServiceChanged(ServiceListenerEntries& receivers,
                                      const ServiceEvent& evt,
                                      ServiceListenerEntries& matchBefore)
{
  int n = 0;

  if (!matchBefore.empty())
  {
    for (auto& l : receivers)
    {
      matchBefore.erase(l);
    }
  }

  for (auto& l : receivers)
  {
    if (!l.IsRemoved())
    {
      try
      {
        ++n;
        l.CallDelegate(evt);
      }
      catch (...)
      {
        std::string message("Service listener in " + l.GetBundleContext().GetBundle().GetSymbolicName() + " threw an exception!");
        SendFrameworkEvent(FrameworkEvent(
            FrameworkEvent::Type::FRAMEWORK_ERROR,
            l.GetBundleContext().GetBundle(),
            message,
            std::current_exception()));
      }
    }
  }

}
void ServiceListeners::BundleChanged(const BundleEvent& evt)
{
  BundleListenerMap filteredBundleListeners;
  coreCtx->bundleHooks.FilterBundleEventReceivers(evt, filteredBundleListeners);

  for(auto& bundleListeners : filteredBundleListeners)
  {
    for (auto& bundleListener : bundleListeners.second)
    {
      try
      {
        std::get<0>(bundleListener.second)(evt);
      }
      catch (...)
      {
        SendFrameworkEvent(FrameworkEvent(
            FrameworkEvent::Type::FRAMEWORK_ERROR,
            MakeBundle(bundleListeners.first->bundle->shared_from_this()),
            std::string("Bundle listener threw an exception"),
            std::current_exception()));
      }
    }
  }
}
Пример #4
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;
        }
      }
    }
  }
}