22 #include "usUtils_p.h"
24 #include "usServiceListeners_p.h"
25 #include "usServiceReferenceBasePrivate.h"
27 #include "usCoreModuleContext_p.h"
34 const int ServiceListeners::OBJECTCLASS_IX = 0;
35 const int ServiceListeners::SERVICE_ID_IX = 1;
37 ServiceListeners::ServiceListeners(CoreModuleContext* coreCtx)
45 void* data,
const std::string& filter)
47 US_UNUSED(Lock(
this));
49 ServiceListenerEntry sle(mc, listener, data, filter);
50 RemoveServiceListener_unlocked(sle);
52 serviceSet.insert(sle);
53 coreCtx->serviceHooks.HandleServiceListenerReg(sle);
60 ServiceListenerEntry entryToRemove(mc, listener, data);
62 US_UNUSED(Lock(
this));
63 RemoveServiceListener_unlocked(entryToRemove);
66 void ServiceListeners::RemoveServiceListener_unlocked(
const ServiceListenerEntry& entryToRemove)
68 ServiceListenerEntries::const_iterator it = serviceSet.find(entryToRemove);
69 if (it != serviceSet.end())
72 coreCtx->serviceHooks.HandleServiceListenerUnreg(*it);
80 MutexLock lock(moduleListenerMapMutex);
81 ModuleListenerMap::value_type::second_type& listeners = moduleListenerMap[mc];
82 if (std::find_if(listeners.begin(), listeners.end(), std::bind1st(ModuleListenerCompare(), std::make_pair(listener, data))) == listeners.end())
84 listeners.push_back(std::make_pair(listener, data));
90 MutexLock lock(moduleListenerMapMutex);
91 moduleListenerMap[mc].remove_if(std::bind1st(ModuleListenerCompare(), std::make_pair(listener, data)));
94 void ServiceListeners::ModuleChanged(
const ModuleEvent& evt)
96 ModuleListenerMap filteredModuleListeners;
97 coreCtx->moduleHooks.FilterModuleEventReceivers(evt, filteredModuleListeners);
99 for(ModuleListenerMap::iterator iter = filteredModuleListeners.begin(), end = filteredModuleListeners.end();
102 for (ModuleListenerMap::mapped_type::iterator iter2 = iter->second.begin(), end2 = iter->second.end();
103 iter2 != end2; ++iter2)
109 catch (
const std::exception& e)
111 US_WARN <<
"Module listener threw an exception: " << e.what();
120 US_UNUSED(Lock(
this));
121 for (ServiceListenerEntries::iterator it = serviceSet.begin();
122 it != serviceSet.end(); )
125 if (it->GetModuleContext() == mc)
127 RemoveFromCache(*it);
128 serviceSet.erase(it++);
138 MutexLock lock(moduleListenerMapMutex);
139 moduleListenerMap.erase(mc);
145 US_UNUSED(Lock(
this));
146 std::vector<ServiceListenerEntry> entries;
147 for (ServiceListenerEntries::iterator it = serviceSet.begin();
148 it != serviceSet.end(); )
150 if (it->GetModuleContext() == mc)
152 entries.push_back(*it);
155 coreCtx->serviceHooks.HandleServiceListenerUnreg(entries);
158 void ServiceListeners::ServiceChanged(ServiceListenerEntries& receivers,
159 const ServiceEvent& evt)
161 ServiceListenerEntries matchBefore;
162 ServiceChanged(receivers, evt, matchBefore);
165 void ServiceListeners::ServiceChanged(ServiceListenerEntries& receivers,
166 const ServiceEvent& evt,
167 ServiceListenerEntries& matchBefore)
171 if (!matchBefore.empty())
173 for (ServiceListenerEntries::const_iterator l = receivers.begin();
174 l != receivers.end(); ++l)
176 matchBefore.erase(*l);
180 for (ServiceListenerEntries::const_iterator l = receivers.begin();
181 l != receivers.end(); ++l)
188 l->CallDelegate(evt);
192 US_WARN <<
"Service listener"
193 <<
" in " << l->GetModuleContext()->GetModule()->GetName()
194 <<
" threw an exception!";
202 void ServiceListeners::GetMatchingServiceListeners(
const ServiceEvent& evt, ServiceListenerEntries& set,
205 US_UNUSED(Lock(
this));
208 ServiceListenerEntries receivers = serviceSet;
209 coreCtx->serviceHooks.FilterServiceEventReceivers(evt, receivers);
212 for (std::list<ServiceListenerEntry>::const_iterator sse = complicatedListeners.begin();
213 sse != complicatedListeners.end(); ++sse)
215 if (receivers.count(*sse) == 0)
continue;
216 const LDAPExpr& ldapExpr = sse->GetLDAPExpr();
217 if (ldapExpr.IsNull() ||
218 ldapExpr.Evaluate(evt.GetServiceReference().d->GetProperties(),
false))
228 const std::vector<std::string> c(
any_cast<std::vector<std::string> >
230 for (std::vector<std::string>::const_iterator objClass = c.begin();
231 objClass != c.end(); ++objClass)
233 AddToSet(set, receivers, OBJECTCLASS_IX, *objClass);
237 std::stringstream ss;
239 AddToSet(set, receivers, SERVICE_ID_IX, ss.str());
242 std::vector<ServiceListenerHook::ListenerInfo> ServiceListeners::GetListenerInfoCollection()
const
244 US_UNUSED(Lock(
this));
245 std::vector<ServiceListenerHook::ListenerInfo> result;
246 result.reserve(serviceSet.size());
247 for (ServiceListenerEntries::const_iterator iter = serviceSet.begin(),
248 iterEnd = serviceSet.end(); iter != iterEnd; ++iter)
250 result.push_back(*iter);
255 void ServiceListeners::RemoveFromCache(
const ServiceListenerEntry& sle)
257 if (!sle.GetLocalCache().empty())
259 for (std::size_t i = 0; i < hashedServiceKeys.size(); ++i)
261 CacheType& keymap = cache[i];
262 std::vector<std::string>& l = sle.GetLocalCache()[i];
263 for (std::vector<std::string>::const_iterator it = l.begin();
266 std::list<ServiceListenerEntry>& sles = keymap[*it];
277 complicatedListeners.remove(sle);
281 void ServiceListeners::CheckSimple(
const ServiceListenerEntry& sle) {
282 if (sle.GetLDAPExpr().IsNull())
284 complicatedListeners.push_back(sle);
288 LDAPExpr::LocalCache local_cache;
289 if (sle.GetLDAPExpr().IsSimple(hashedServiceKeys, local_cache,
false))
291 sle.GetLocalCache() = local_cache;
292 for (std::size_t i = 0; i < hashedServiceKeys.size(); ++i)
294 for (std::vector<std::string>::const_iterator it = local_cache[i].begin();
295 it != local_cache[i].end(); ++it)
297 std::list<ServiceListenerEntry>& sles = cache[i][*it];
305 complicatedListeners.push_back(sle);
310 void ServiceListeners::AddToSet(ServiceListenerEntries& set,
311 const ServiceListenerEntries& receivers,
312 int cache_ix,
const std::string& val)
314 std::list<ServiceListenerEntry>& l = cache[cache_ix][val];
319 for (std::list<ServiceListenerEntry>::const_iterator entry = l.begin();
320 entry != l.end(); ++entry)
322 if (receivers.count(*entry))
ValueType * any_cast(Any *operand)
US_MODULE_LISTENER_FUNCTOR ModuleListener
US_BEGIN_NAMESPACE typedef US_SERVICE_LISTENER_FUNCTOR ServiceListener
US_Core_EXPORT const std::string & OBJECTCLASS()
US_Core_EXPORT const std::string & SERVICE_ID()