]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTConfigurationHandler.cxx
schedule registration of configuration if handler is inactive, and register when...
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTConfigurationHandler.cxx
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"
40 #include "AliHLTErrorGuard.h"
41 #include "TMap.h"
42 #include "TObjString.h"
43
44 /** ROOT macro for the implementation of ROOT specific class methods */
45 ClassImp(AliHLTConfigurationHandler)
46
47 AliHLTConfigurationHandler::AliHLTConfigurationHandler()
48   : AliHLTLogging()
49   , fgListConfigurations()
50   , fgListScheduledRegistrations()
51   , fFlags(0)
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   }
71   fgListScheduledRegistrations.Delete();
72 }
73
74 AliHLTConfigurationHandler* AliHLTConfigurationHandler::fgpInstance=NULL;
75 int AliHLTConfigurationHandler::fgNofInstances=0;
76 TMap* AliHLTConfigurationHandler::fgpSubstitutions=NULL;
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) {
91     nofInstances=--fgNofInstances;
92   }
93   if (fgNofInstances==0) {
94     fgpInstance = NULL;
95     if (fgpSubstitutions) delete fgpSubstitutions;
96     fgpSubstitutions=NULL;
97   }
98   if (nofInstances==0) delete this;
99   return nofInstances;
100 }
101
102
103 int AliHLTConfigurationHandler::RegisterConfiguration(AliHLTConfiguration* pConf)
104 {
105   // see header file for function documentation
106   int iResult=0;
107   if (pConf) {
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         }
129       }
130     } else if (IsScheduling()) {
131       fgListScheduledRegistrations.Add(pClone);
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;
143   AliHLTConfiguration* pConf= new AliHLTConfiguration(id, component, sources, arguments);
144   if (pConf) {
145     // the configuration will be registered automatically, if this failes the configuration
146     // is missing -> delete it
147     if (FindConfiguration(id)==NULL) {
148       delete pConf;
149       pConf=NULL;
150       iResult=-EEXIST;
151     }
152   } else {
153     HLTError("system error: object allocation failed");
154     iResult=-ENOMEM;
155   }
156   return iResult;
157 }
158
159 void AliHLTConfigurationHandler::PrintConfigurations()
160 {
161   // see header file for function documentation
162   HLTLogKeyword("configuration listing");
163   HLTMessage("registered configurations:");
164   TObjLink *lnk = fgListConfigurations.FirstLink();
165   while (lnk) {
166     TObject *obj = lnk->GetObject();
167     HLTMessage("  %s", obj->GetName());
168     lnk = lnk->Next();
169   }
170 }
171
172 void AliHLTConfigurationHandler::Print(const char* option)
173 {
174   // print info
175   TString argument(option);
176   if (argument.BeginsWith("treeroot=")) {
177     argument.ReplaceAll("treeroot=", "");
178     if (argument.IsNull()) {
179       cout << "invalid argument to option 'treeroot=', please specify configuration" << endl;
180       return;
181     }
182     // TODO: add functionality to print a dependency tree beginning from a root configuration
183     // add also option to limit the depth
184     cout << "need to implement option 'treeview', argument " << argument << endl;
185     return;
186   }
187
188   // default: print all
189   PrintConfigurations();
190 }
191
192 int AliHLTConfigurationHandler::RemoveConfiguration(const char* id)
193 {
194   // see header file for function documentation
195   int iResult=0;
196   if (id) {
197     AliHLTConfiguration* pConf=NULL;
198     if ((pConf=FindConfiguration(id))!=NULL) {
199       iResult=RemoveConfiguration(pConf);
200       delete pConf;
201       pConf=NULL;
202     } else {
203       HLTWarning("can not find configuration \"%s\"", id);
204       iResult=-ENOENT;
205     }
206   } else {
207     iResult=-EINVAL;
208   }
209   return iResult;
210 }
211
212 int AliHLTConfigurationHandler::RemoveConfiguration(AliHLTConfiguration* pConf)
213 {
214   // see header file for function documentation
215   int iResult=0;
216   if (pConf) {
217     // remove the configuration from the list
218     HLTDebug("remove configuration \"%s\"", pConf->GetName());
219     fgListConfigurations.Remove(pConf);
220     // remove cross links in the remaining configurations
221     TObjLink* lnk=fgListConfigurations.FirstLink();
222     while (lnk && iResult>=0) {
223       AliHLTConfiguration* pRem=(AliHLTConfiguration*)lnk->GetObject();
224       if (pRem) {
225         pRem->InvalidateSource(pConf);
226       } else {
227         iResult=-EFAULT;
228       }
229       lnk=lnk->Next();
230     }
231   }
232   return iResult;
233 }
234
235 AliHLTConfiguration* AliHLTConfigurationHandler::FindConfiguration(const char* id)
236 {
237   // see header file for function documentation
238   AliHLTConfiguration* pConf=NULL;
239   if (id) {
240     pConf=(AliHLTConfiguration*)fgListConfigurations.FindObject(id); 
241   }
242   return pConf;
243 }
244
245 int AliHLTConfigurationHandler::Deactivate(bool schedule) {
246   // see header file for function documentation
247   fFlags|=kInactive;
248   if (schedule)
249     fFlags|=kScheduling;
250   return 0;
251 }
252
253 int AliHLTConfigurationHandler::Activate() {
254   // see header file for function documentation
255   fFlags&=~kInactive;
256   if (IsScheduling()) {
257     fFlags&=~kScheduling;
258     TObjLink *lnk = fgListScheduledRegistrations.FirstLink();
259     while (lnk) {
260       RegisterConfiguration((AliHLTConfiguration*)lnk->GetObject());
261       lnk = lnk->Next();
262     }
263     ClearScheduledRegistrations();
264   }
265   return 0;
266 }
267
268 int AliHLTConfigurationHandler::MissedRegistration(const char* name)
269 {
270   /// indicate a failed attempt to register because of unavailable global instance
271
272   /// everything fine if global instance is inactive
273   if (fgpInstance) {
274     if (fgpInstance->IsActive()) {
275       static AliHLTErrorGuard g("AliHLTConfigurationHandler", "MissedRegistration",
276                                 "internal error, global instance available but registration of configuration failed");
277       (++g).Throw(1);
278     }
279     return 0;
280   }
281   TString message("Missing configuration handler, failed to register configuration");
282   if (name) {message+=" '"; message+=name;}
283   message+="'\n AliHLTSystem and configuration handler can be initialized by adding the line";
284   message+="\n    AliHLTSystem* pHLT=AliHLTPluginBase::GetInstance();";
285   message+="\n to the macro before the first AliHLTConfiguration definition. Suppressing further messages.\n";
286   static AliHLTErrorGuard g("AliHLTConfigurationHandler", "MissedRegistration", message.Data());
287   (++g).Throw(1);
288   return 1;
289 }
290
291 int AliHLTConfigurationHandler::AddSubstitution(const char* componentId, const AliHLTConfiguration& subst)
292 {
293   /// add component substitution for components of specified id
294   if (!componentId) return -EINVAL;
295   if (!fgpSubstitutions) fgpSubstitutions=new TMap;
296   if (!fgpSubstitutions) return -ENOMEM;
297   fgpSubstitutions->SetOwnerKeyValue(kTRUE);
298
299   fgpSubstitutions->Add(new TObjString(componentId), new AliHLTConfiguration(subst));
300
301   return 0;  
302 }
303
304 int AliHLTConfigurationHandler::AddSubstitution(const AliHLTConfiguration& conf , const AliHLTConfiguration& subst)
305 {
306   /// add component substitution for components of specified id
307   if (!fgpSubstitutions) fgpSubstitutions=new TMap;
308   if (!fgpSubstitutions) return -ENOMEM;
309   fgpSubstitutions->SetOwnerKeyValue(kTRUE);
310
311   fgpSubstitutions->Add(new AliHLTConfiguration(conf), new AliHLTConfiguration(subst));
312
313   return 0;  
314 }
315
316 const AliHLTConfiguration* AliHLTConfigurationHandler::FindSubstitution(const AliHLTConfiguration& conf)
317 {
318   /// find component substitution for a configuration
319   if (!fgpSubstitutions) return NULL;
320   TObject* value=NULL;
321
322   // check for specific configuration
323   value=fgpSubstitutions->GetValue(conf.GetName());
324   if (value) return dynamic_cast<AliHLTConfiguration*>(value);
325
326   // check for component Id
327   value=fgpSubstitutions->GetValue(conf.GetComponentID());
328   if (value) return dynamic_cast<AliHLTConfiguration*>(value);
329
330   return NULL;
331 }