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