bugfix #83123: registration of configurations in multiple handlers. The bug caused...
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTConfigurationHandler.cxx
CommitLineData
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
32using 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 */
45ClassImp(AliHLTConfigurationHandler)
46
47AliHLTConfigurationHandler::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
61AliHLTConfigurationHandler::~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 74AliHLTConfigurationHandler* AliHLTConfigurationHandler::fgpInstance=NULL;
75int AliHLTConfigurationHandler::fgNofInstances=0;
e7b1a4ad 76TMap* AliHLTConfigurationHandler::fgpSubstitutions=NULL;
b005ef92 77
78AliHLTConfigurationHandler* AliHLTConfigurationHandler::CreateHandler()
79{
80 // see header file for class documentation
81 if (!fgpInstance) fgpInstance=new AliHLTConfigurationHandler;
82 fgNofInstances++;
83 return fgpInstance;
84}
85
86int 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 103int 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
139int 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
176void 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 189void 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 209int 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
229int 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
252AliHLTConfiguration* 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 262int 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
270int 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 285int 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 308int 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
321int 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
333const 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}