Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
usModuleRegistry.cpp
Go to the documentation of this file.
1 /*=============================================================================
2 
3  Library: CppMicroServices
4 
5  Copyright (c) German Cancer Research Center,
6  Division of Medical and Biological Informatics
7 
8  Licensed under the Apache License, Version 2.0 (the "License");
9  you may not use this file except in compliance with the License.
10  You may obtain a copy of the License at
11 
12  http://www.apache.org/licenses/LICENSE-2.0
13 
14  Unless required by applicable law or agreed to in writing, software
15  distributed under the License is distributed on an "AS IS" BASIS,
16  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  See the License for the specific language governing permissions and
18  limitations under the License.
19 
20 =============================================================================*/
21 
22 #include "usModuleRegistry.h"
23 
24 #include "usModule.h"
25 #include "usModuleInfo.h"
26 #include "usModuleContext.h"
27 #include "usModuleActivator.h"
28 #include "usModuleInitialization.h"
29 #include "usCoreModuleContext_p.h"
30 #include "usGetModuleContext.h"
31 #include "usStaticInit_p.h"
32 
33 #include <cassert>
34 #include <map>
35 
36 
37 US_BEGIN_NAMESPACE
38 
39 typedef US_UNORDERED_MAP_TYPE<std::string, Module*> ModuleMap;
40 
41 US_GLOBAL_STATIC(CoreModuleContext, coreModuleContext)
42 
43 template<typename T>
44 struct ModuleDeleter
45 {
46  void operator()(GlobalStatic<T>& globalStatic) const
47  {
48  ModuleMap* moduleMap = globalStatic.pointer;
49  for (ModuleMap::const_iterator i = moduleMap->begin();
50  i != moduleMap->end(); ++i)
51  {
52  delete i->second;
53  }
54  DefaultGlobalStaticDeleter<T> defaultDeleter;
55  defaultDeleter(globalStatic);
56  }
57 };
58 
63 US_GLOBAL_STATIC_WITH_DELETER(ModuleMap, modules, ModuleDeleter)
64 
65 
68 US_GLOBAL_STATIC(Mutex, modulesLock)
69 
73 US_GLOBAL_STATIC(Mutex, countLock)
74 
75 void ModuleRegistry::Register(ModuleInfo* info)
76 {
77  static long regCount = 0;
78  if (info->id > 0)
79  {
80  // The module was already registered
81  Module* module = 0;
82  {
83  MutexLock lock(*modulesLock());
84  module = modules()->operator[](info->name);
85  assert(module != 0);
86  }
87  module->Start();
88  }
89  else
90  {
91  Module* module = 0;
92  // check if the module is reloaded
93  {
94  MutexLock lock(*modulesLock());
95  ModuleMap* map = modules();
96  for (ModuleMap::const_iterator i = map->begin();
97  i != map->end(); ++i)
98  {
99  if (i->second->GetLocation() == info->location &&
100  i->second->GetName() == info->name)
101  {
102  module = i->second;
103  info->id = module->GetModuleId();
104  }
105  }
106  }
107 
108  if (!module)
109  {
110  module = new Module();
111  countLock()->Lock();
112  info->id = ++regCount;
113  assert(info->id == 1 ? info->name == "CppMicroServices" : true);
114  countLock()->Unlock();
115 
116  module->Init(coreModuleContext(), info);
117 
118  MutexLock lock(*modulesLock());
119  ModuleMap* map = modules();
120  map->insert(std::make_pair(info->name, module));
121  }
122  else
123  {
124  module->Init(coreModuleContext(), info);
125  }
126 
127  module->Start();
128  }
129 }
130 
131 void ModuleRegistry::UnRegister(const ModuleInfo* info)
132 {
133  if (info->id > 1)
134  {
135  Module* curr = 0;
136  {
137  MutexLock lock(*modulesLock());
138  curr = modules()->operator[](info->name);
139  assert(curr != 0);
140  }
141  curr->Stop();
142  }
143 }
144 
145 Module* ModuleRegistry::GetModule(long id)
146 {
147  MutexLock lock(*modulesLock());
148 
149  ModuleMap::const_iterator iter = modules()->begin();
150  ModuleMap::const_iterator iterEnd = modules()->end();
151  for (; iter != iterEnd; ++iter)
152  {
153  if (iter->second->GetModuleId() == id)
154  {
155  return iter->second;
156  }
157  }
158  return 0;
159 }
160 
161 Module* ModuleRegistry::GetModule(const std::string& name)
162 {
163  MutexLock lock(*modulesLock());
164 
165  ModuleMap::const_iterator iter = modules()->find(name);
166  if (iter != modules()->end())
167  {
168  return iter->second;
169  }
170  return 0;
171 }
172 
173 std::vector<Module*> ModuleRegistry::GetModules()
174 {
175  MutexLock lock(*modulesLock());
176 
177  std::vector<Module*> result;
178  ModuleMap* map = modules();
179  ModuleMap::const_iterator iter = map->begin();
180  ModuleMap::const_iterator iterEnd = map->end();
181  for (; iter != iterEnd; ++iter)
182  {
183  result.push_back(iter->second);
184  }
185  return result;
186 }
187 
188 std::vector<Module*> ModuleRegistry::GetLoadedModules()
189 {
190  MutexLock lock(*modulesLock());
191 
192  std::vector<Module*> result;
193  ModuleMap::const_iterator iter = modules()->begin();
194  ModuleMap::const_iterator iterEnd = modules()->end();
195  for (; iter != iterEnd; ++iter)
196  {
197  if (iter->second->IsLoaded())
198  {
199  result.push_back(iter->second);
200  }
201  }
202  return result;
203 }
204 
205 // Control the static initialization order for several core objects
206 struct StaticInitializationOrder
207 {
208  StaticInitializationOrder()
209  {
210  ModuleSettings::GetLogLevel();
211  modulesLock();
212  countLock();
213  modules();
214  coreModuleContext();
215  }
216 };
217 
218 static StaticInitializationOrder _staticInitializationOrder;
219 
220 US_END_NAMESPACE
221 
222 // We initialize the CppMicroService module after making sure
223 // that all other global statics have been initialized above
US_UNORDERED_MAP_TYPE< std::string, Module * > ModuleMap
static void info(const char *fmt,...)
Definition: svm.cpp:100
#define US_INITIALIZE_MODULE
Creates initialization code for a module.
static StaticInitializationOrder _staticInitializationOrder
std::string name
Definition: usModuleInfo.h:47
long GetModuleId() const
Definition: usModule.cpp:211