]>
Commit | Line | Data |
---|---|---|
7a436c89 | 1 | // $Id$ |
2 | // splitted from AliHLTConfiguration.cxx,v 1.25 2007/10/12 13:24:47 | |
3 | /************************************************************************** | |
4 | * This file is property of and copyright by the ALICE HLT Project * | |
5 | * ALICE Experiment at CERN, All rights reserved. * | |
6 | * * | |
7 | * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> * | |
8 | * for The ALICE HLT Project. * | |
9 | * * | |
10 | * Permission to use, copy, modify and distribute this software and its * | |
11 | * documentation strictly for non-commercial purposes is hereby granted * | |
12 | * without fee, provided that the above copyright notice appears in all * | |
13 | * copies and that both the copyright notice and this permission notice * | |
14 | * appear in the supporting documentation. The authors make no claims * | |
15 | * about the suitability of this software for any purpose. It is * | |
16 | * provided "as is" without express or implied warranty. * | |
17 | **************************************************************************/ | |
18 | ||
19 | /** @file AliHLTConfigurationHandler.cxx | |
20 | @author Matthias Richter | |
21 | @date | |
22 | @brief Implementation of HLT tasks. | |
23 | */ | |
24 | ||
25 | // see header file for class documentation | |
26 | // or | |
27 | // refer to README to build package | |
28 | // or | |
29 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt | |
30 | ||
31 | #if __GNUC__>= 3 | |
32 | using namespace std; | |
33 | #endif | |
34 | ||
35 | #include <cerrno> | |
36 | #include <iostream> | |
37 | #include <string> | |
38 | #include "AliHLTConfigurationHandler.h" | |
39 | #include "AliHLTConfiguration.h" | |
4403fb69 | 40 | #include "AliHLTErrorGuard.h" |
e7b1a4ad | 41 | #include "TMap.h" |
42 | #include "TObjString.h" | |
7a436c89 | 43 | |
44 | /** ROOT macro for the implementation of ROOT specific class methods */ | |
45 | ClassImp(AliHLTConfigurationHandler) | |
46 | ||
47 | AliHLTConfigurationHandler::AliHLTConfigurationHandler() | |
4403fb69 | 48 | : AliHLTLogging() |
49 | , fgListConfigurations() | |
ef802306 | 50 | , fgListScheduledRegistrations() |
4403fb69 | 51 | , fFlags(0) |
7a436c89 | 52 | { |
53 | // see header file for class documentation | |
54 | // or | |
55 | // refer to README to build package | |
56 | // or | |
57 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt | |
58 | SetLocalLoggingLevel(kHLTLogInfo); | |
59 | } | |
60 | ||
61 | AliHLTConfigurationHandler::~AliHLTConfigurationHandler() | |
62 | { | |
63 | // see header file for function documentation | |
64 | TObjLink* lnk=NULL; | |
65 | while ((lnk=fgListConfigurations.FirstLink())!=NULL) { | |
66 | AliHLTConfiguration* pConf=(AliHLTConfiguration*)lnk->GetObject(); | |
67 | HLTDebug("delete configuration \"%s\"", pConf->GetName()); | |
68 | fgListConfigurations.Remove(lnk); | |
69 | delete pConf; | |
70 | } | |
ef802306 | 71 | fgListScheduledRegistrations.Delete(); |
7a436c89 | 72 | } |
73 | ||
b005ef92 | 74 | AliHLTConfigurationHandler* AliHLTConfigurationHandler::fgpInstance=NULL; |
75 | int AliHLTConfigurationHandler::fgNofInstances=0; | |
e7b1a4ad | 76 | TMap* AliHLTConfigurationHandler::fgpSubstitutions=NULL; |
b005ef92 | 77 | |
78 | AliHLTConfigurationHandler* AliHLTConfigurationHandler::CreateHandler() | |
79 | { | |
80 | // see header file for class documentation | |
81 | if (!fgpInstance) fgpInstance=new AliHLTConfigurationHandler; | |
82 | fgNofInstances++; | |
83 | return fgpInstance; | |
84 | } | |
85 | ||
86 | int AliHLTConfigurationHandler::Destroy() | |
87 | { | |
88 | // see header file for class documentation | |
89 | int nofInstances=0; | |
90 | if (fgpInstance==this) { | |
153e7db5 | 91 | nofInstances=--fgNofInstances; |
b005ef92 | 92 | } |
66efe0e1 | 93 | if (fgNofInstances==0) { |
66efe0e1 | 94 | fgpInstance = NULL; |
e7b1a4ad | 95 | if (fgpSubstitutions) delete fgpSubstitutions; |
96 | fgpSubstitutions=NULL; | |
66efe0e1 | 97 | } |
153e7db5 | 98 | if (nofInstances==0) delete this; |
b005ef92 | 99 | return nofInstances; |
100 | } | |
101 | ||
102 | ||
7a436c89 | 103 | int AliHLTConfigurationHandler::RegisterConfiguration(AliHLTConfiguration* pConf) |
104 | { | |
105 | // see header file for function documentation | |
106 | int iResult=0; | |
107 | if (pConf) { | |
ef802306 | 108 | AliHLTConfiguration* pClone=new AliHLTConfiguration(*pConf); |
109 | if (IsActive()) { | |
110 | AliHLTConfiguration* pExisting=NULL; | |
111 | if ((pExisting=FindConfiguration(pConf->GetName())) == NULL) { | |
112 | fgListConfigurations.Add(pClone); | |
113 | HLTDebug("configuration \"%s\" (%p) registered from %p", pClone->GetName(), pClone, pConf); | |
114 | ||
115 | // mark all configurations with unresolved dependencies for re-evaluation | |
116 | TObjLink* lnk=fgListConfigurations.FirstLink(); | |
117 | while (lnk) { | |
118 | AliHLTConfiguration* pSrc=(AliHLTConfiguration*)lnk->GetObject(); | |
119 | if (pSrc && pSrc!=pClone && pSrc->SourcesResolved()!=1) { | |
120 | pSrc->InvalidateSources(); | |
121 | } | |
122 | lnk=lnk->Next(); | |
123 | } | |
124 | } else { | |
125 | if ((*pExisting)!=(*pConf)) { | |
126 | iResult=-EEXIST; | |
127 | HLTWarning("configuration \"%s\" already registered with different properties", pConf->GetName()); | |
128 | } | |
d4a18597 | 129 | } |
ef802306 | 130 | } else if (IsScheduling()) { |
131 | fgListScheduledRegistrations.Add(pClone); | |
7a436c89 | 132 | } |
133 | } else { | |
134 | iResult=-EINVAL; | |
135 | } | |
136 | return iResult; | |
137 | } | |
138 | ||
139 | int AliHLTConfigurationHandler::CreateConfiguration(const char* id, const char* component, const char* sources, const char* arguments) | |
140 | { | |
141 | // see header file for function documentation | |
142 | int iResult=0; | |
a806b72c | 143 | // if this handler is the global instance the configuration is added |
144 | // automatically in the creation of the AliHLTConfiguration object | |
145 | // the global instance must be deactivated otherwise in order to just create | |
146 | // the object and then add it to THIS handler | |
147 | bool bIamGlobal=fgpInstance==this; | |
148 | if (!bIamGlobal && fgpInstance) { | |
149 | // deactivate the automatic registration in the global handler | |
150 | fgpInstance->Deactivate(false); | |
151 | } | |
7a436c89 | 152 | AliHLTConfiguration* pConf= new AliHLTConfiguration(id, component, sources, arguments); |
153 | if (pConf) { | |
a806b72c | 154 | if (bIamGlobal) { |
7a436c89 | 155 | // the configuration will be registered automatically, if this failes the configuration |
156 | // is missing -> delete it | |
157 | if (FindConfiguration(id)==NULL) { | |
158 | delete pConf; | |
159 | pConf=NULL; | |
160 | iResult=-EEXIST; | |
161 | } | |
a806b72c | 162 | } else { |
163 | RegisterConfiguration(pConf); | |
164 | } | |
7a436c89 | 165 | } else { |
166 | HLTError("system error: object allocation failed"); | |
167 | iResult=-ENOMEM; | |
168 | } | |
a806b72c | 169 | if (!bIamGlobal && fgpInstance) { |
170 | // deactivate the automatic registration in the global handler | |
171 | fgpInstance->Activate(); | |
172 | } | |
7a436c89 | 173 | return iResult; |
174 | } | |
175 | ||
176 | void AliHLTConfigurationHandler::PrintConfigurations() | |
177 | { | |
178 | // see header file for function documentation | |
179 | HLTLogKeyword("configuration listing"); | |
180 | HLTMessage("registered configurations:"); | |
181 | TObjLink *lnk = fgListConfigurations.FirstLink(); | |
182 | while (lnk) { | |
183 | TObject *obj = lnk->GetObject(); | |
184 | HLTMessage(" %s", obj->GetName()); | |
185 | lnk = lnk->Next(); | |
186 | } | |
187 | } | |
188 | ||
4403fb69 | 189 | void AliHLTConfigurationHandler::Print(const char* option) |
190 | { | |
191 | // print info | |
192 | TString argument(option); | |
193 | if (argument.BeginsWith("treeroot=")) { | |
194 | argument.ReplaceAll("treeroot=", ""); | |
195 | if (argument.IsNull()) { | |
196 | cout << "invalid argument to option 'treeroot=', please specify configuration" << endl; | |
197 | return; | |
198 | } | |
199 | // TODO: add functionality to print a dependency tree beginning from a root configuration | |
200 | // add also option to limit the depth | |
201 | cout << "need to implement option 'treeview', argument " << argument << endl; | |
202 | return; | |
203 | } | |
204 | ||
205 | // default: print all | |
206 | PrintConfigurations(); | |
207 | } | |
208 | ||
7a436c89 | 209 | int AliHLTConfigurationHandler::RemoveConfiguration(const char* id) |
210 | { | |
211 | // see header file for function documentation | |
212 | int iResult=0; | |
213 | if (id) { | |
214 | AliHLTConfiguration* pConf=NULL; | |
215 | if ((pConf=FindConfiguration(id))!=NULL) { | |
216 | iResult=RemoveConfiguration(pConf); | |
217 | delete pConf; | |
218 | pConf=NULL; | |
219 | } else { | |
220 | HLTWarning("can not find configuration \"%s\"", id); | |
221 | iResult=-ENOENT; | |
222 | } | |
223 | } else { | |
224 | iResult=-EINVAL; | |
225 | } | |
226 | return iResult; | |
227 | } | |
228 | ||
229 | int AliHLTConfigurationHandler::RemoveConfiguration(AliHLTConfiguration* pConf) | |
230 | { | |
231 | // see header file for function documentation | |
232 | int iResult=0; | |
233 | if (pConf) { | |
234 | // remove the configuration from the list | |
235 | HLTDebug("remove configuration \"%s\"", pConf->GetName()); | |
236 | fgListConfigurations.Remove(pConf); | |
237 | // remove cross links in the remaining configurations | |
238 | TObjLink* lnk=fgListConfigurations.FirstLink(); | |
239 | while (lnk && iResult>=0) { | |
240 | AliHLTConfiguration* pRem=(AliHLTConfiguration*)lnk->GetObject(); | |
241 | if (pRem) { | |
242 | pRem->InvalidateSource(pConf); | |
243 | } else { | |
244 | iResult=-EFAULT; | |
245 | } | |
246 | lnk=lnk->Next(); | |
247 | } | |
248 | } | |
249 | return iResult; | |
250 | } | |
251 | ||
252 | AliHLTConfiguration* AliHLTConfigurationHandler::FindConfiguration(const char* id) | |
253 | { | |
254 | // see header file for function documentation | |
255 | AliHLTConfiguration* pConf=NULL; | |
256 | if (id) { | |
257 | pConf=(AliHLTConfiguration*)fgListConfigurations.FindObject(id); | |
258 | } | |
259 | return pConf; | |
260 | } | |
261 | ||
ef802306 | 262 | int AliHLTConfigurationHandler::Deactivate(bool schedule) { |
263 | // see header file for function documentation | |
264 | fFlags|=kInactive; | |
265 | if (schedule) | |
266 | fFlags|=kScheduling; | |
267 | return 0; | |
268 | } | |
269 | ||
270 | int AliHLTConfigurationHandler::Activate() { | |
271 | // see header file for function documentation | |
272 | fFlags&=~kInactive; | |
273 | if (IsScheduling()) { | |
274 | fFlags&=~kScheduling; | |
275 | TObjLink *lnk = fgListScheduledRegistrations.FirstLink(); | |
276 | while (lnk) { | |
277 | RegisterConfiguration((AliHLTConfiguration*)lnk->GetObject()); | |
278 | lnk = lnk->Next(); | |
279 | } | |
280 | ClearScheduledRegistrations(); | |
281 | } | |
282 | return 0; | |
283 | } | |
284 | ||
4403fb69 | 285 | int AliHLTConfigurationHandler::MissedRegistration(const char* name) |
286 | { | |
287 | /// indicate a failed attempt to register because of unavailable global instance | |
288 | ||
289 | /// everything fine if global instance is inactive | |
290 | if (fgpInstance) { | |
291 | if (fgpInstance->IsActive()) { | |
292 | static AliHLTErrorGuard g("AliHLTConfigurationHandler", "MissedRegistration", | |
293 | "internal error, global instance available but registration of configuration failed"); | |
294 | (++g).Throw(1); | |
295 | } | |
296 | return 0; | |
297 | } | |
298 | TString message("Missing configuration handler, failed to register configuration"); | |
299 | if (name) {message+=" '"; message+=name;} | |
300 | message+="'\n AliHLTSystem and configuration handler can be initialized by adding the line"; | |
301 | message+="\n AliHLTSystem* pHLT=AliHLTPluginBase::GetInstance();"; | |
302 | message+="\n to the macro before the first AliHLTConfiguration definition. Suppressing further messages.\n"; | |
303 | static AliHLTErrorGuard g("AliHLTConfigurationHandler", "MissedRegistration", message.Data()); | |
304 | (++g).Throw(1); | |
305 | return 1; | |
306 | } | |
307 | ||
e7b1a4ad | 308 | int AliHLTConfigurationHandler::AddSubstitution(const char* componentId, const AliHLTConfiguration& subst) |
309 | { | |
310 | /// add component substitution for components of specified id | |
311 | if (!componentId) return -EINVAL; | |
312 | if (!fgpSubstitutions) fgpSubstitutions=new TMap; | |
313 | if (!fgpSubstitutions) return -ENOMEM; | |
314 | fgpSubstitutions->SetOwnerKeyValue(kTRUE); | |
315 | ||
316 | fgpSubstitutions->Add(new TObjString(componentId), new AliHLTConfiguration(subst)); | |
317 | ||
318 | return 0; | |
319 | } | |
320 | ||
321 | int AliHLTConfigurationHandler::AddSubstitution(const AliHLTConfiguration& conf , const AliHLTConfiguration& subst) | |
322 | { | |
323 | /// add component substitution for components of specified id | |
324 | if (!fgpSubstitutions) fgpSubstitutions=new TMap; | |
325 | if (!fgpSubstitutions) return -ENOMEM; | |
326 | fgpSubstitutions->SetOwnerKeyValue(kTRUE); | |
327 | ||
328 | fgpSubstitutions->Add(new AliHLTConfiguration(conf), new AliHLTConfiguration(subst)); | |
329 | ||
330 | return 0; | |
331 | } | |
332 | ||
333 | const AliHLTConfiguration* AliHLTConfigurationHandler::FindSubstitution(const AliHLTConfiguration& conf) | |
334 | { | |
335 | /// find component substitution for a configuration | |
336 | if (!fgpSubstitutions) return NULL; | |
337 | TObject* value=NULL; | |
338 | ||
339 | // check for specific configuration | |
340 | value=fgpSubstitutions->GetValue(conf.GetName()); | |
341 | if (value) return dynamic_cast<AliHLTConfiguration*>(value); | |
342 | ||
343 | // check for component Id | |
344 | value=fgpSubstitutions->GetValue(conf.GetComponentID()); | |
345 | if (value) return dynamic_cast<AliHLTConfiguration*>(value); | |
346 | ||
347 | return NULL; | |
348 | } |