diff --git a/Core/Code/CppMicroServices/src/module/usModuleAbstractTracked.tpp b/Core/Code/CppMicroServices/src/module/usModuleAbstractTracked.tpp index a40324c462..d344538f03 100644 --- a/Core/Code/CppMicroServices/src/module/usModuleAbstractTracked.tpp +++ b/Core/Code/CppMicroServices/src/module/usModuleAbstractTracked.tpp @@ -1,314 +1,314 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #include US_BEGIN_NAMESPACE template -const bool ModuleAbstractTracked::DEBUG = false; +const bool ModuleAbstractTracked::DEBUG_OUTPUT = false; template ModuleAbstractTracked::ModuleAbstractTracked() { closed = false; } template ModuleAbstractTracked::~ModuleAbstractTracked() { } template void ModuleAbstractTracked::SetInitial(const std::list& initiallist) { initial = initiallist; - if (DEBUG) + if (DEBUG_OUTPUT) { for(typename std::list::const_iterator item = initiallist.begin(); item != initiallist.end(); ++item) { US_DEBUG << "ModuleAbstractTracked::setInitial: " << (*item); } } } template void ModuleAbstractTracked::TrackInitial() { while (true) { S item(0); { typename Self::Lock l(this); if (closed || (initial.size() == 0)) { /* * if there are no more initial items */ return; /* we are done */ } /* * move the first item from the initial list to the adding list * within this synchronized block. */ item = initial.front(); initial.pop_front(); if (tracked[item]) { /* if we are already tracking this item */ - US_DEBUG(DEBUG) << "ModuleAbstractTracked::trackInitial[already tracked]: " << item; + US_DEBUG(DEBUG_OUTPUT) << "ModuleAbstractTracked::trackInitial[already tracked]: " << item; continue; /* skip this item */ } if (std::find(adding.begin(), adding.end(), item) != adding.end()) { /* * if this item is already in the process of being added. */ - US_DEBUG(DEBUG) << "ModuleAbstractTracked::trackInitial[already adding]: " << item; + US_DEBUG(DEBUG_OUTPUT) << "ModuleAbstractTracked::trackInitial[already adding]: " << item; continue; /* skip this item */ } adding.push_back(item); } - US_DEBUG(DEBUG) << "ModuleAbstractTracked::trackInitial: " << item; + US_DEBUG(DEBUG_OUTPUT) << "ModuleAbstractTracked::trackInitial: " << item; TrackAdding(item, R()); /* * Begin tracking it. We call trackAdding * since we have already put the item in the * adding list. */ } } template void ModuleAbstractTracked::Close() { closed = true; } template void ModuleAbstractTracked::Track(S item, R related) { T object(0); { typename Self::Lock l(this); if (closed) { return; } object = tracked[item]; if (!object) { /* we are not tracking the item */ if (std::find(adding.begin(), adding.end(),item) != adding.end()) { /* if this item is already in the process of being added. */ - US_DEBUG(DEBUG) << "ModuleAbstractTracked::track[already adding]: " << item; + US_DEBUG(DEBUG_OUTPUT) << "ModuleAbstractTracked::track[already adding]: " << item; return; } adding.push_back(item); /* mark this item is being added */ } else { /* we are currently tracking this item */ - US_DEBUG(DEBUG) << "ModuleAbstractTracked::track[modified]: " << item; + US_DEBUG(DEBUG_OUTPUT) << "ModuleAbstractTracked::track[modified]: " << item; Modified(); /* increment modification count */ } } if (!object) { /* we are not tracking the item */ TrackAdding(item, related); } else { /* Call customizer outside of synchronized region */ CustomizerModified(item, related, object); /* * If the customizer throws an unchecked exception, it is safe to * let it propagate */ } } template void ModuleAbstractTracked::Untrack(S item, R related) { T object(0); { typename Self::Lock l(this); std::size_t initialSize = initial.size(); initial.remove(item); if (initialSize != initial.size()) { /* if this item is already in the list * of initial references to process */ - US_DEBUG(DEBUG) << "ModuleAbstractTracked::untrack[removed from initial]: " << item; + US_DEBUG(DEBUG_OUTPUT) << "ModuleAbstractTracked::untrack[removed from initial]: " << item; return; /* we have removed it from the list and it will not be * processed */ } std::size_t addingSize = adding.size(); adding.remove(item); if (addingSize != adding.size()) { /* if the item is in the process of * being added */ - US_DEBUG(DEBUG) << "ModuleAbstractTracked::untrack[being added]: " << item; + US_DEBUG(DEBUG_OUTPUT) << "ModuleAbstractTracked::untrack[being added]: " << item; return; /* * in case the item is untracked while in the process of * adding */ } object = tracked[item]; /* * must remove from tracker before * calling customizer callback */ tracked.erase(item); if (!object) { /* are we actually tracking the item */ return; } Modified(); /* increment modification count */ } - US_DEBUG(DEBUG) << "ModuleAbstractTracked::untrack[removed]: " << item; + US_DEBUG(DEBUG_OUTPUT) << "ModuleAbstractTracked::untrack[removed]: " << item; /* Call customizer outside of synchronized region */ CustomizerRemoved(item, related, object); /* * If the customizer throws an unchecked exception, it is safe to let it * propagate */ } template std::size_t ModuleAbstractTracked::Size() const { return tracked.size(); } template bool ModuleAbstractTracked::IsEmpty() const { return tracked.empty(); } template T ModuleAbstractTracked::GetCustomizedObject(S item) const { typename TrackingMap::const_iterator i = tracked.find(item); if (i != tracked.end()) return i->second; return T(); } template void ModuleAbstractTracked::GetTracked(std::list& items) const { for (typename TrackingMap::const_iterator i = tracked.begin(); i != tracked.end(); ++i) { items.push_back(i->first); } } template void ModuleAbstractTracked::Modified() { trackingCount.Ref(); } template int ModuleAbstractTracked::GetTrackingCount() const { return trackingCount; } template void ModuleAbstractTracked::CopyEntries(TrackingMap& map) const { map.insert(tracked.begin(), tracked.end()); } template bool ModuleAbstractTracked::CustomizerAddingFinal(S item, const T& custom) { typename Self::Lock l(this); std::size_t addingSize = adding.size(); adding.remove(item); if (addingSize != adding.size() && !closed) { /* * if the item was not untracked during the customizer * callback */ if (custom) { tracked[item] = custom; Modified(); /* increment modification count */ this->NotifyAll(); /* notify any waiters */ } return false; } else { return true; } } template void ModuleAbstractTracked::TrackAdding(S item, R related) { - US_DEBUG(DEBUG) << "ModuleAbstractTracked::trackAdding:" << item; + US_DEBUG(DEBUG_OUTPUT) << "ModuleAbstractTracked::trackAdding:" << item; T object(0); bool becameUntracked = false; /* Call customizer outside of synchronized region */ try { object = CustomizerAdding(item, related); becameUntracked = this->CustomizerAddingFinal(item, object); } catch (...) { /* * If the customizer throws an exception, it will * propagate after the cleanup code. */ this->CustomizerAddingFinal(item, object); throw; } /* * The item became untracked during the customizer callback. */ if (becameUntracked && object) { - US_DEBUG(DEBUG) << "ModuleAbstractTracked::trackAdding[removed]: " << item; + US_DEBUG(DEBUG_OUTPUT) << "ModuleAbstractTracked::trackAdding[removed]: " << item; /* Call customizer outside of synchronized region */ CustomizerRemoved(item, related, object); /* * If the customizer throws an unchecked exception, it is safe to * let it propagate */ } } US_END_NAMESPACE diff --git a/Core/Code/CppMicroServices/src/module/usModuleAbstractTracked_p.h b/Core/Code/CppMicroServices/src/module/usModuleAbstractTracked_p.h index 982c97d99d..ccdc3627d4 100644 --- a/Core/Code/CppMicroServices/src/module/usModuleAbstractTracked_p.h +++ b/Core/Code/CppMicroServices/src/module/usModuleAbstractTracked_p.h @@ -1,291 +1,291 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USMODULEABSTRACTTRACKED_H #define USMODULEABSTRACTTRACKED_H #include #include "usAtomicInt_p.h" #include "usAny.h" US_BEGIN_NAMESPACE /** * This class is not intended to be used directly. It is exported to support * the CppMicroServices module system. * * Abstract class to track items. If a Tracker is reused (closed then reopened), * then a new ModuleAbstractTracked object is used. This class acts as a map of tracked * item -> customized object. Subclasses of this class will act as the listener * object for the tracker. This class is used to synchronize access to the * tracked items. This is not a public class. It is only for use by the * implementation of the Tracker class. * * @tparam S The tracked item. It is the key. * @tparam T The value mapped to the tracked item. * @tparam R The reason the tracked item is being tracked or untracked. * @ThreadSafe */ template class ModuleAbstractTracked : public US_DEFAULT_THREADING > { public: /* set this to true to compile in debug messages */ - static const bool DEBUG; // = false; + static const bool DEBUG_OUTPUT; // = false; typedef std::map TrackingMap; /** * ModuleAbstractTracked constructor. */ ModuleAbstractTracked(); virtual ~ModuleAbstractTracked(); /** * Set initial list of items into tracker before events begin to be * received. * * This method must be called from Tracker's open method while synchronized * on this object in the same synchronized block as the add listener call. * * @param list The initial list of items to be tracked. null * entries in the list are ignored. * @GuardedBy this */ void SetInitial(const std::list& list); /** * Track the initial list of items. This is called after events can begin to * be received. * * This method must be called from Tracker's open method while not * synchronized on this object after the add listener call. * */ void TrackInitial(); /** * Called by the owning Tracker object when it is closed. */ void Close(); /** * Begin to track an item. * * @param item S to be tracked. * @param related Action related object. */ void Track(S item, R related); /** * Discontinue tracking the item. * * @param item S to be untracked. * @param related Action related object. */ void Untrack(S item, R related); /** * Returns the number of tracked items. * * @return The number of tracked items. * * @GuardedBy this */ std::size_t Size() const; /** * Returns if the tracker is empty. * * @return Whether the tracker is empty. * * @GuardedBy this */ bool IsEmpty() const; /** * Return the customized object for the specified item * * @param item The item to lookup in the map * @return The customized object for the specified item. * * @GuardedBy this */ T GetCustomizedObject(S item) const; /** * Return the list of tracked items. * * @return The tracked items. * @GuardedBy this */ void GetTracked(std::list& items) const; /** * Increment the modification count. If this method is overridden, the * overriding method MUST call this method to increment the tracking count. * * @GuardedBy this */ virtual void Modified(); /** * Returns the tracking count for this ServiceTracker object. * * The tracking count is initialized to 0 when this object is opened. Every * time an item is added, modified or removed from this object the tracking * count is incremented. * * @GuardedBy this * @return The tracking count for this object. */ int GetTrackingCount() const; /** * Copy the tracked items and associated values into the specified map. * * @param map The map into which to copy the tracked items and associated * values. This map must not be a user provided map so that user code * is not executed while synchronized on this. * @return The specified map. * @GuardedBy this */ void CopyEntries(TrackingMap& map) const; /** * Call the specific customizer adding method. This method must not be * called while synchronized on this object. * * @param item S to be tracked. * @param related Action related object. * @return Customized object for the tracked item or null if * the item is not to be tracked. */ virtual T CustomizerAdding(S item, const R& related) = 0; /** * Call the specific customizer modified method. This method must not be * called while synchronized on this object. * * @param item Tracked item. * @param related Action related object. * @param object Customized object for the tracked item. */ virtual void CustomizerModified(S item, const R& related, T object) = 0; /** * Call the specific customizer removed method. This method must not be * called while synchronized on this object. * * @param item Tracked item. * @param related Action related object. * @param object Customized object for the tracked item. */ virtual void CustomizerRemoved(S item, const R& related, T object) = 0; /** * List of items in the process of being added. This is used to deal with * nesting of events. Since events may be synchronously delivered, events * can be nested. For example, when processing the adding of a service and * the customizer causes the service to be unregistered, notification to the * nested call to untrack that the service was unregistered can be made to * the track method. * * Since the std::vector implementation is not synchronized, all access to * this list must be protected by the same synchronized object for * thread-safety. * * @GuardedBy this */ std::list adding; /** * true if the tracked object is closed. * * This field is volatile because it is set by one thread and read by * another. */ volatile bool closed; /** * Initial list of items for the tracker. This is used to correctly process * the initial items which could be modified before they are tracked. This * is necessary since the initial set of tracked items are not "announced" * by events and therefore the event which makes the item untracked could be * delivered before we track the item. * * An item must not be in both the initial and adding lists at the same * time. An item must be moved from the initial list to the adding list * "atomically" before we begin tracking it. * * Since the LinkedList implementation is not synchronized, all access to * this list must be protected by the same synchronized object for * thread-safety. * * @GuardedBy this */ std::list initial; /** * Common logic to add an item to the tracker used by track and * trackInitial. The specified item must have been placed in the adding list * before calling this method. * * @param item S to be tracked. * @param related Action related object. */ void TrackAdding(S item, R related); private: typedef ModuleAbstractTracked Self; /** * Map of tracked items to customized objects. * * @GuardedBy this */ TrackingMap tracked; /** * Modification count. This field is initialized to zero and incremented by * modified. * * @GuardedBy this */ AtomicInt trackingCount; bool CustomizerAddingFinal(S item, const T& custom); }; US_END_NAMESPACE #include "usModuleAbstractTracked.tpp" #endif // USMODULEABSTRACTTRACKED_H diff --git a/Core/Code/CppMicroServices/src/service/usServiceTracker.tpp b/Core/Code/CppMicroServices/src/service/usServiceTracker.tpp index 17ab4757a5..608c628c61 100644 --- a/Core/Code/CppMicroServices/src/service/usServiceTracker.tpp +++ b/Core/Code/CppMicroServices/src/service/usServiceTracker.tpp @@ -1,448 +1,448 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #include "usServiceTrackerPrivate.h" #include "usTrackedService_p.h" #include "usServiceException.h" #include "usModuleContext.h" #include #include US_BEGIN_NAMESPACE template ServiceTracker::~ServiceTracker() { Close(); delete d; } #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4355) #endif template ServiceTracker::ServiceTracker(ModuleContext* context, const ServiceReference& reference, _ServiceTrackerCustomizer* customizer) : d(new _ServiceTrackerPrivate(this, context, reference, customizer)) { } template ServiceTracker::ServiceTracker(ModuleContext* context, const std::string& clazz, _ServiceTrackerCustomizer* customizer) : d(new _ServiceTrackerPrivate(this, context, clazz, customizer)) { } template ServiceTracker::ServiceTracker(ModuleContext* context, const LDAPFilter& filter, _ServiceTrackerCustomizer* customizer) : d(new _ServiceTrackerPrivate(this, context, filter, customizer)) { } template ServiceTracker::ServiceTracker(ModuleContext *context, ServiceTrackerCustomizer *customizer) : d(new _ServiceTrackerPrivate(this, context, us_service_interface_iid(), customizer)) { const char* clazz = us_service_interface_iid(); if (clazz == 0) throw ServiceException("The service interface class has no US_DECLARE_SERVICE_INTERFACE macro"); } #ifdef _MSC_VER #pragma warning(pop) #endif template void ServiceTracker::Open() { _TrackedService* t; { typename _ServiceTrackerPrivate::Lock l(d); if (d->trackedService) { return; } - US_DEBUG(d->DEBUG) << "ServiceTracker::Open: " << d->filter; + US_DEBUG(d->DEBUG_OUTPUT) << "ServiceTracker::Open: " << d->filter; t = new _TrackedService(this, d->customizer); { typename _TrackedService::Lock l(*t); try { d->context->AddServiceListener(t, &_TrackedService::ServiceChanged, d->listenerFilter); std::list references; if (!d->trackClass.empty()) { references = d->GetInitialReferences(d->trackClass, std::string()); } else { if (d->trackReference.GetModule() != 0) { references.push_back(d->trackReference); } else { /* user supplied filter */ references = d->GetInitialReferences(std::string(), (d->listenerFilter.empty()) ? d->filter.ToString() : d->listenerFilter); } } /* set tracked with the initial references */ t->SetInitial(references); } catch (const std::invalid_argument& e) { throw std::runtime_error(std::string("unexpected std::invalid_argument exception: ") + e.what()); } } d->trackedService = t; } /* Call tracked outside of synchronized region */ t->TrackInitial(); /* process the initial references */ } template void ServiceTracker::Close() { _TrackedService* outgoing; std::list references; { typename _ServiceTrackerPrivate::Lock l(d); outgoing = d->trackedService; if (outgoing == 0) { return; } - US_DEBUG(d->DEBUG) << "ServiceTracker::close:" << d->filter; + US_DEBUG(d->DEBUG_OUTPUT) << "ServiceTracker::close:" << d->filter; outgoing->Close(); GetServiceReferences(references); d->trackedService = 0; try { d->context->RemoveServiceListener(outgoing, &_TrackedService::ServiceChanged); } catch (const std::logic_error& /*e*/) { /* In case the context was stopped. */ } } d->Modified(); /* clear the cache */ { typename _TrackedService::Lock l(outgoing); outgoing->NotifyAll(); /* wake up any waiters */ } for(std::list::const_iterator ref = references.begin(); ref != references.end(); ++ref) { outgoing->Untrack(*ref, ServiceEvent()); } - if (d->DEBUG) + if (d->DEBUG_OUTPUT) { typename _ServiceTrackerPrivate::Lock l(d); if ((d->cachedReference.GetModule() == 0) && (d->cachedService == 0)) { US_DEBUG(true) << "ServiceTracker::close[cached cleared]:" << d->filter; } } delete outgoing; d->trackedService = 0; } template T ServiceTracker::WaitForService(unsigned long timeoutMillis) { T object = GetService(); while (object == 0) { _TrackedService* t = d->Tracked(); if (t == 0) { /* if ServiceTracker is not open */ return 0; } { typename _TrackedService::Lock l(t); if (t->Size() == 0) { t->Wait(timeoutMillis); } } object = GetService(); } return object; } template void ServiceTracker::GetServiceReferences(std::list& refs) const { _TrackedService* t = d->Tracked(); if (t == 0) { /* if ServiceTracker is not open */ return; } { typename _TrackedService::Lock l(t); d->GetServiceReferences_unlocked(refs, t); } } template ServiceReference ServiceTracker::GetServiceReference() const { ServiceReference reference(0); { typename _ServiceTrackerPrivate::Lock l(d); reference = d->cachedReference; } if (reference.GetModule() != 0) { - US_DEBUG(d->DEBUG) << "ServiceTracker::getServiceReference[cached]:" + US_DEBUG(d->DEBUG_OUTPUT) << "ServiceTracker::getServiceReference[cached]:" << d->filter; return reference; } - US_DEBUG(d->DEBUG) << "ServiceTracker::getServiceReference:" << d->filter; + US_DEBUG(d->DEBUG_OUTPUT) << "ServiceTracker::getServiceReference:" << d->filter; std::list references; GetServiceReferences(references); std::size_t length = references.size(); if (length == 0) { /* if no service is being tracked */ throw ServiceException("No service is being tracked"); } std::list::const_iterator selectedRef; if (length > 1) { /* if more than one service, select highest ranking */ std::vector rankings(length); int count = 0; int maxRanking = std::numeric_limits::min(); std::list::const_iterator refIter = references.begin(); for (std::size_t i = 0; i < length; i++) { Any rankingAny = refIter->GetProperty(ServiceConstants::SERVICE_RANKING()); int ranking = 0; if (rankingAny.Type() == typeid(int)) { ranking = any_cast(rankingAny); } rankings[i] = ranking; if (ranking > maxRanking) { selectedRef = refIter; maxRanking = ranking; count = 1; } else { if (ranking == maxRanking) { count++; } } ++refIter; } if (count > 1) { /* if still more than one service, select lowest id */ long int minId = std::numeric_limits::max(); refIter = references.begin(); for (std::size_t i = 0; i < length; i++) { if (rankings[i] == maxRanking) { Any idAny = refIter->GetProperty(ServiceConstants::SERVICE_ID()); long int id = 0; if (idAny.Type() == typeid(long int)) { id = any_cast(idAny); } if (id < minId) { selectedRef = refIter; minId = id; } } ++refIter; } } } { typename _ServiceTrackerPrivate::Lock l(d); d->cachedReference = *selectedRef; return d->cachedReference; } } template T ServiceTracker::GetService(const ServiceReference& reference) const { _TrackedService* t = d->Tracked(); if (t == 0) { /* if ServiceTracker is not open */ return 0; } { typename _TrackedService::Lock l(t); return t->GetCustomizedObject(reference); } } template void ServiceTracker::GetServices(std::list& services) const { _TrackedService* t = d->Tracked(); if (t == 0) { /* if ServiceTracker is not open */ return; } { typename _TrackedService::Lock l(t); std::list references; d->GetServiceReferences_unlocked(references, t); for(std::list::const_iterator ref = references.begin(); ref != references.end(); ++ref) { services.push_back(t->GetCustomizedObject(*ref)); } } } template T ServiceTracker::GetService() const { T service = d->cachedService; if (service != 0) { - US_DEBUG(d->DEBUG) << "ServiceTracker::getService[cached]:" + US_DEBUG(d->DEBUG_OUTPUT) << "ServiceTracker::getService[cached]:" << d->filter; return service; } - US_DEBUG(d->DEBUG) << "ServiceTracker::getService:" << d->filter; + US_DEBUG(d->DEBUG_OUTPUT) << "ServiceTracker::getService:" << d->filter; try { ServiceReference reference = GetServiceReference(); if (reference.GetModule() == 0) { return 0; } return d->cachedService = GetService(reference); } catch (const ServiceException&) { return 0; } } template void ServiceTracker::Remove(const ServiceReference& reference) { _TrackedService* t = d->Tracked(); if (t == 0) { /* if ServiceTracker is not open */ return; } t->Untrack(reference, ServiceEvent()); } template int ServiceTracker::Size() const { _TrackedService* t = d->Tracked(); if (t == 0) { /* if ServiceTracker is not open */ return 0; } { typename _TrackedService::Lock l(t); return static_cast(t->Size()); } } template int ServiceTracker::GetTrackingCount() const { _TrackedService* t = d->Tracked(); if (t == 0) { /* if ServiceTracker is not open */ return -1; } { typename _TrackedService::Lock l(t); return t->GetTrackingCount(); } } template void ServiceTracker::GetTracked(TrackingMap& map) const { _TrackedService* t = d->Tracked(); if (t == 0) { /* if ServiceTracker is not open */ return; } { typename _TrackedService::Lock l(t); t->CopyEntries(map); } } template bool ServiceTracker::IsEmpty() const { _TrackedService* t = d->Tracked(); if (t == 0) { /* if ServiceTracker is not open */ return true; } { typename _TrackedService::Lock l(t); return t->IsEmpty(); } } template T ServiceTracker::AddingService(const ServiceReference& reference) { return dynamic_cast(d->context->GetService(reference)); } template void ServiceTracker::ModifiedService(const ServiceReference& /*reference*/, T /*service*/) { /* do nothing */ } template void ServiceTracker::RemovedService(const ServiceReference& reference, T /*service*/) { d->context->UngetService(reference); } US_END_NAMESPACE diff --git a/Core/Code/CppMicroServices/src/service/usServiceTrackerPrivate.h b/Core/Code/CppMicroServices/src/service/usServiceTrackerPrivate.h index 2bb0dfcb0a..1229b68ca0 100644 --- a/Core/Code/CppMicroServices/src/service/usServiceTrackerPrivate.h +++ b/Core/Code/CppMicroServices/src/service/usServiceTrackerPrivate.h @@ -1,172 +1,172 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef USSERVICETRACKERPRIVATE_H #define USSERVICETRACKERPRIVATE_H #include "usServiceReference.h" #include "usLDAPFilter.h" US_BEGIN_NAMESPACE /** * \ingroup MicroServices */ template class ServiceTrackerPrivate : US_DEFAULT_THREADING > { public: ServiceTrackerPrivate(ServiceTracker* st, ModuleContext* context, const ServiceReference& reference, ServiceTrackerCustomizer* customizer); ServiceTrackerPrivate(ServiceTracker* st, ModuleContext* context, const std::string& clazz, ServiceTrackerCustomizer* customizer); ServiceTrackerPrivate(ServiceTracker* st, ModuleContext* context, const LDAPFilter& filter, ServiceTrackerCustomizer* customizer); ~ServiceTrackerPrivate(); /** * Returns the list of initial ServiceReferences that will be * tracked by this ServiceTracker. * * @param className The class name with which the service was registered, or * null for all services. * @param filterString The filter criteria or null for all * services. * @return The list of initial ServiceReferences. * @throws std::invalid_argument If the specified filterString has an * invalid syntax. */ std::list GetInitialReferences(const std::string& className, const std::string& filterString); void GetServiceReferences_unlocked(std::list& refs, TrackedService* t) const; /* set this to true to compile in debug messages */ - static const bool DEBUG; // = false; + static const bool DEBUG_OUTPUT; // = false; /** * The Module Context used by this ServiceTracker. */ ModuleContext* const context; /** * The filter used by this ServiceTracker which specifies the * search criteria for the services to track. */ LDAPFilter filter; /** * The ServiceTrackerCustomizer for this tracker. */ ServiceTrackerCustomizer* customizer; /** * Filter string for use when adding the ServiceListener. If this field is * set, then certain optimizations can be taken since we don't have a user * supplied filter. */ std::string listenerFilter; /** * Class name to be tracked. If this field is set, then we are tracking by * class name. */ std::string trackClass; /** * Reference to be tracked. If this field is set, then we are tracking a * single ServiceReference. */ ServiceReference trackReference; /** * Tracked services: ServiceReference -> customized Object and * ServiceListenerEntry object */ TrackedService* trackedService; /** * Accessor method for the current TrackedService object. This method is only * intended to be used by the unsynchronized methods which do not modify the * trackedService field. * * @return The current Tracked object. */ TrackedService* Tracked() const; /** * Called by the TrackedService object whenever the set of tracked services is * modified. Clears the cache. */ /* * This method must not be synchronized since it is called by TrackedService while * TrackedService is synchronized. We don't want synchronization interactions * between the listener thread and the user thread. */ void Modified(); /** * Cached ServiceReference for getServiceReference. */ mutable ServiceReference cachedReference; /** * Cached service object for GetService. * * This field is volatile since it is accessed by multiple threads. */ mutable T volatile cachedService; private: inline ServiceTracker* q_func() { return static_cast *>(q_ptr); } inline const ServiceTracker* q_func() const { return static_cast *>(q_ptr); } friend class ServiceTracker; ServiceTracker * const q_ptr; }; US_END_NAMESPACE #include "usServiceTrackerPrivate.tpp" #endif // USSERVICETRACKERPRIVATE_H diff --git a/Core/Code/CppMicroServices/src/service/usServiceTrackerPrivate.tpp b/Core/Code/CppMicroServices/src/service/usServiceTrackerPrivate.tpp index 5346e14b40..e48033f6a1 100644 --- a/Core/Code/CppMicroServices/src/service/usServiceTrackerPrivate.tpp +++ b/Core/Code/CppMicroServices/src/service/usServiceTrackerPrivate.tpp @@ -1,144 +1,144 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #include "usTrackedService_p.h" #include "usModuleContext.h" #include "usLDAPFilter.h" #include US_BEGIN_NAMESPACE template -const bool ServiceTrackerPrivate::DEBUG = true; +const bool ServiceTrackerPrivate::DEBUG_OUTPUT = true; template ServiceTrackerPrivate::ServiceTrackerPrivate( ServiceTracker* st, ModuleContext* context, const ServiceReference& reference, ServiceTrackerCustomizer* customizer) : context(context), customizer(customizer), trackReference(reference), trackedService(0), cachedReference(0), cachedService(0), q_ptr(st) { this->customizer = customizer ? customizer : q_func(); std::stringstream ss; ss << "(" << ServiceConstants::SERVICE_ID() << "=" << any_cast(reference.GetProperty(ServiceConstants::SERVICE_ID())) << ")"; this->listenerFilter = ss.str(); try { this->filter = LDAPFilter(listenerFilter); } catch (const std::invalid_argument& e) { /* * we could only get this exception if the ServiceReference was * invalid */ std::invalid_argument ia(std::string("unexpected std::invalid_argument exception: ") + e.what()); throw ia; } } template ServiceTrackerPrivate::ServiceTrackerPrivate( ServiceTracker* st, ModuleContext* context, const std::string& clazz, ServiceTrackerCustomizer* customizer) : context(context), customizer(customizer), trackClass(clazz), trackReference(0), trackedService(0), cachedReference(0), cachedService(0), q_ptr(st) { this->customizer = customizer ? customizer : q_func(); this->listenerFilter = std::string("(") + US_PREPEND_NAMESPACE(ServiceConstants)::OBJECTCLASS() + "=" + clazz + ")"; try { this->filter = LDAPFilter(listenerFilter); } catch (const std::invalid_argument& e) { /* * we could only get this exception if the clazz argument was * malformed */ std::invalid_argument ia( std::string("unexpected std::invalid_argument exception: ") + e.what()); throw ia; } } template ServiceTrackerPrivate::ServiceTrackerPrivate( ServiceTracker* st, ModuleContext* context, const LDAPFilter& filter, ServiceTrackerCustomizer* customizer) : context(context), filter(filter), customizer(customizer), listenerFilter(filter.ToString()), trackReference(0), trackedService(0), cachedReference(0), cachedService(0), q_ptr(st) { this->customizer = customizer ? customizer : q_func(); if (context == 0) { throw std::invalid_argument("The module context cannot be null."); } } template ServiceTrackerPrivate::~ServiceTrackerPrivate() { } template std::list ServiceTrackerPrivate::GetInitialReferences( const std::string& className, const std::string& filterString) { return context->GetServiceReferences(className, filterString); } template void ServiceTrackerPrivate::GetServiceReferences_unlocked(std::list& refs, TrackedService* t) const { if (t->Size() == 0) { return; } t->GetTracked(refs); } template TrackedService* ServiceTrackerPrivate::Tracked() const { return trackedService; } template void ServiceTrackerPrivate::Modified() { cachedReference = 0; /* clear cached value */ cachedService = 0; /* clear cached value */ - US_DEBUG(DEBUG) << "ServiceTracker::Modified(): " << filter; + US_DEBUG(DEBUG_OUTPUT) << "ServiceTracker::Modified(): " << filter; } US_END_NAMESPACE diff --git a/Core/Code/CppMicroServices/src/service/usTrackedService.tpp b/Core/Code/CppMicroServices/src/service/usTrackedService.tpp index e1c1f709c0..8917c200fd 100644 --- a/Core/Code/CppMicroServices/src/service/usTrackedService.tpp +++ b/Core/Code/CppMicroServices/src/service/usTrackedService.tpp @@ -1,123 +1,123 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ US_BEGIN_NAMESPACE template TrackedService::TrackedService(ServiceTracker* serviceTracker, ServiceTrackerCustomizer* customizer) : serviceTracker(serviceTracker), customizer(customizer) { } template void TrackedService::ServiceChanged(const ServiceEvent event) { /* * Check if we had a delayed call (which could happen when we * close). */ if (this->closed) { return; } ServiceReference reference = event.GetServiceReference(); - US_DEBUG(serviceTracker->d->DEBUG) << "TrackedService::ServiceChanged[" + US_DEBUG(serviceTracker->d->DEBUG_OUTPUT) << "TrackedService::ServiceChanged[" << event.GetType() << "]: " << reference; switch (event.GetType()) { case ServiceEvent::REGISTERED : case ServiceEvent::MODIFIED : { if (!serviceTracker->d->listenerFilter.empty()) { // service listener added with filter this->Track(reference, event); /* * If the customizer throws an unchecked exception, it * is safe to let it propagate */ } else { // service listener added without filter if (serviceTracker->d->filter.Match(reference)) { this->Track(reference, event); /* * If the customizer throws an unchecked exception, * it is safe to let it propagate */ } else { this->Untrack(reference, event); /* * If the customizer throws an unchecked exception, * it is safe to let it propagate */ } } break; } case ServiceEvent::MODIFIED_ENDMATCH : case ServiceEvent::UNREGISTERING : this->Untrack(reference, event); /* * If the customizer throws an unchecked exception, it is * safe to let it propagate */ break; } } template void TrackedService::Modified() { Superclass::Modified(); /* increment the modification count */ serviceTracker->d->Modified(); } template T TrackedService::CustomizerAdding(ServiceReference item, const ServiceEvent& /*related*/) { return customizer->AddingService(item); } template void TrackedService::CustomizerModified(ServiceReference item, const ServiceEvent& /*related*/, T object) { customizer->ModifiedService(item, object); } template void TrackedService::CustomizerRemoved(ServiceReference item, const ServiceEvent& /*related*/, T object) { customizer->RemovedService(item, object); } US_END_NAMESPACE