diff --git a/Core/Code/Common/mitkCoreServices.cpp b/Core/Code/Common/mitkCoreServices.cpp index 410e697029..aace1f5d05 100644 --- a/Core/Code/Common/mitkCoreServices.cpp +++ b/Core/Code/Common/mitkCoreServices.cpp @@ -1,75 +1,81 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkCoreServices.h" #include "mitkIShaderRepository.h" #include "usGetModuleContext.h" #include "usModuleContext.h" #include "usServiceReference.h" +#include +#include + namespace mitk { +static itk::SimpleFastMutexLock s_ContextToServicesMapMutex; +static std::map > s_ContextToServicesMap; + template -S* GetCoreService(us::ModuleContext* context, std::map >& csm) +static S* GetCoreService(us::ModuleContext* context) { + itk::MutexLockHolder l(s_ContextToServicesMapMutex); S* coreService = NULL; us::ServiceReference serviceRef = context->GetServiceReference(); if (serviceRef) { coreService = context->GetService(serviceRef); } assert(coreService && "Asserting non-NULL MITK core service"); - csm[context].insert(std::make_pair(coreService,serviceRef)); + s_ContextToServicesMap[context].insert(std::make_pair(coreService,serviceRef)); return coreService; } -std::map > CoreServices::m_ContextToServicesMap; - IShaderRepository* CoreServices::GetShaderRepository(us::ModuleContext* context) { - return GetCoreService(context, m_ContextToServicesMap); + return GetCoreService(context); } bool CoreServices::Unget(us::ModuleContext* context, const std::string& /*interfaceId*/, void* service) { bool success = false; - std::map >::iterator iter = m_ContextToServicesMap.find(context); - if (iter != m_ContextToServicesMap.end()) + itk::MutexLockHolder l(s_ContextToServicesMapMutex); + std::map >::iterator iter = s_ContextToServicesMap.find(context); + if (iter != s_ContextToServicesMap.end()) { std::map::iterator iter2 = iter->second.find(service); if (iter2 != iter->second.end()) { us::ServiceReferenceU serviceRef = iter2->second; if (serviceRef) { success = context->UngetService(serviceRef); if (success) { iter->second.erase(iter2); } } } } return success; } } diff --git a/Core/Code/Common/mitkCoreServices.h b/Core/Code/Common/mitkCoreServices.h index 32ddf9cec2..0ddb3ee961 100644 --- a/Core/Code/Common/mitkCoreServices.h +++ b/Core/Code/Common/mitkCoreServices.h @@ -1,140 +1,138 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKCORESERVICES_H #define MITKCORESERVICES_H #include "MitkExports.h" #include #include #include #include #include #include namespace mitk { struct IShaderRepository; /** * @brief Access MITK core services. * * This class can be used to conveniently access common * MITK Core service objects. All getter methods are guaranteed * to return a non-NULL service object. * * To ensure that CoreServices::Unget() is called after the caller * has finished using a service object, you should use the CoreServicePointer * helper class which calls Unget() when it goes out of scope: * * \code * CoreServicePointer shaderRepo(CoreServices::GetShaderRepository()); * // Do something with shaderRepo * \endcode * * @see CoreServicePointer */ class MITK_CORE_EXPORT CoreServices { public: /** * @brief Get a IShaderRepository instance. * @param context The module context of the module getting the service. * @return A non-NULL IShaderRepository instance. */ static IShaderRepository* GetShaderRepository(us::ModuleContext* context = us::GetModuleContext()); /** * @brief Unget a previously acquired service instance. * @param service The service instance to be released. * @return \c true if ungetting the service was successful, \c false otherwise. */ template static bool Unget(S* service, us::ModuleContext* context = us::GetModuleContext()) { return Unget(context, us_service_interface_iid(), service); } private: static bool Unget(us::ModuleContext* context, const std::string& interfaceId, void* service); - static std::map > m_ContextToServicesMap; - // purposely not implemented CoreServices(); CoreServices(const CoreServices&); CoreServices& operator=(const CoreServices&); }; /** * @brief A RAII helper class for core service objects. * * This is class is intended for usage in local scopes; it calls * CoreServices::Unget(S*) in its destructor. You should not construct * multiple CoreServicePointer instances using the same service pointer, * unless it is retrieved by a new call to a CoreServices getter method. * * @see CoreServices */ template class CoreServicePointer { public: explicit CoreServicePointer(S* service) : m_service(service) { assert(m_service); } ~CoreServicePointer() { try { CoreServices::Unget(m_service); } catch (const std::exception& e) { MITK_ERROR << e.what(); } catch (...) { MITK_ERROR << "Ungetting core service failed."; } } S* operator->() const { return m_service; } private: // purposely not implemented CoreServicePointer(const CoreServicePointer&); CoreServicePointer& operator=(const CoreServicePointer&); S* const m_service; }; } #endif // MITKCORESERVICES_H