void ServiceListeners::HooksBundleStopped(const std::shared_ptr<BundleContextPrivate>& context) { std::vector<ServiceListenerEntry> entries; { auto l = this->Lock(); US_UNUSED(l); for (auto& sle : serviceSet) { if (sle.GetBundleContext() == MakeBundleContext(context)) { entries.push_back(sle); } } } coreCtx->serviceHooks.HandleServiceListenerUnreg(entries); }
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; } } } } }