]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTConfiguration.cxx
adding a component for statistics and monitoring of the DAQ readout list
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTConfiguration.cxx
1 // $Id$
2
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   AliHLTConfiguration.cxx
20     @author Matthias Richter
21     @date   
22     @brief  Implementation of HLT configurations.
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 "AliHLTConfiguration.h"
37 #include "AliHLTConfigurationHandler.h"
38 #include "AliHLTTask.h"
39 #include "AliHLTComponent.h"
40 #include "AliHLTComponentHandler.h"
41 #include <iostream>
42 #include <string>
43 #include "TList.h"
44
45 /** ROOT macro for the implementation of ROOT specific class methods */
46 ClassImp(AliHLTConfiguration)
47
48 AliHLTConfiguration::AliHLTConfiguration()
49   :
50   fID(""),
51   fComponent(""),
52   fStringSources(""),
53   fNofSources(-1),
54   fListSources(),
55   fListSrcElement(),
56   fArguments(""),
57   fArgc(-1),
58   fArgv(NULL),
59   fBufferSize(-1)
60
61   // see header file for class documentation
62   // or
63   // refer to README to build package
64   // or
65   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
66
67   fListSrcElement=fListSources.begin();
68 }
69
70 AliHLTConfiguration::AliHLTConfiguration(const char* id, const char* component, const char* sources,
71                                          const char* arguments, const char* bufsize)
72   :
73   fID(id),
74   fComponent(component),
75   fStringSources(sources),
76   fNofSources(-1),
77   fListSources(),
78   fListSrcElement(),
79   fArguments(arguments),
80   fArgc(-1),
81   fArgv(NULL),
82   fBufferSize(-1)
83 {
84   // see header file for function documentation
85   if (bufsize) fBufferSize=ConvertSizeString(bufsize);
86   fListSrcElement=fListSources.begin();
87   if (id && component) {
88     if (fgConfigurationHandler) {
89       fgConfigurationHandler->RegisterConfiguration(this);
90     } else {
91       HLTError("no configuration handler set, abort registration");
92     }
93   }
94 }
95
96 AliHLTConfiguration::AliHLTConfiguration(const AliHLTConfiguration& src)
97   :
98   TObject(),
99   AliHLTLogging(),
100   fID(src.fID),
101   fComponent(src.fComponent),
102   fStringSources(src.fStringSources),
103   fNofSources(-1),
104   fListSources(),
105   fListSrcElement(),
106   fArguments(src.fArguments),
107   fArgc(-1),
108   fArgv(NULL),
109   fBufferSize(src.fBufferSize)
110
111   // see header file for function documentation
112   fListSrcElement=fListSources.begin();
113 }
114
115 AliHLTConfiguration& AliHLTConfiguration::operator=(const AliHLTConfiguration& src)
116
117   // see header file for function documentation
118   fID=src.fID;
119   fComponent=src.fComponent;
120   fStringSources=src.fStringSources;
121   fNofSources=-1;
122   fArguments=src.fArguments;
123   fArgc=-1;
124   fArgv=NULL;
125   fBufferSize=src.fBufferSize;
126   return *this;
127 }
128
129 AliHLTConfiguration::~AliHLTConfiguration()
130 {
131   // see header file for function documentation
132   if (fgConfigurationHandler) {
133     if (fgConfigurationHandler->FindConfiguration(fID.Data())!=NULL) {
134       fgConfigurationHandler->RemoveConfiguration(this);
135     }
136   }
137   if (fArgv != NULL) {
138     if (fArgc>0) {
139       for (int i=0; i<fArgc; i++) {
140         delete[] fArgv[i];
141       }
142     }
143     delete[] fArgv;
144     fArgv=NULL;
145   }
146
147   vector<AliHLTConfiguration*>::iterator element=fListSources.begin();
148   while (element!=fListSources.end()) {
149     fListSources.erase(element);
150     element=fListSources.begin();
151   }
152 }
153
154 /* the global configuration handler which is used to automatically register the configuration
155  */
156 AliHLTConfigurationHandler* AliHLTConfiguration::fgConfigurationHandler=NULL;
157
158 int AliHLTConfiguration::GlobalInit(AliHLTConfigurationHandler* pHandler)
159 {
160   // see header file for function documentation
161   int iResult=0;
162   if (fgConfigurationHandler!=NULL && fgConfigurationHandler!=pHandler) {
163     fgConfigurationHandler->Logging(kHLTLogWarning, "AliHLTConfiguration::GlobalInit", HLT_DEFAULT_LOG_KEYWORD, "configuration handler already initialized, overriding object %p with %p", fgConfigurationHandler, pHandler);
164   }
165   fgConfigurationHandler=pHandler;
166   return iResult;
167 }
168
169 int AliHLTConfiguration::GlobalDeinit(AliHLTConfigurationHandler* pHandler)
170 {
171   // see header file for function documentation
172   int iResult=0;
173   if (fgConfigurationHandler!=NULL && fgConfigurationHandler!=pHandler) {
174     fgConfigurationHandler->Logging(kHLTLogWarning, "AliHLTConfiguration::GlobalDeinit", HLT_DEFAULT_LOG_KEYWORD, "handler %p is not set, skip ...", pHandler);
175     return -EBADF;
176   }
177   fgConfigurationHandler=NULL;
178   return iResult;
179 }
180
181 const char* AliHLTConfiguration::GetName() const 
182 {
183   // see header file for function documentation
184   if (!fID.IsNull())
185     return fID.Data();
186   return TObject::GetName();
187 }
188
189 AliHLTConfiguration* AliHLTConfiguration::GetSource(const char* id)
190 {
191   // see header file for function documentation
192   AliHLTConfiguration* pSrc=NULL;
193   if (id) {
194     // first check the current element
195     if (fListSrcElement!=fListSources.end() && strcmp(id, (*fListSrcElement)->GetName())==0) {
196       pSrc=*fListSrcElement;
197       } else {
198       // check the list
199
200       pSrc=GetFirstSource();
201       while (pSrc) {
202         if (strcmp(id, pSrc->GetName())==0)
203           break;
204         pSrc=GetNextSource();
205       }
206     }
207   }
208   return pSrc;
209 }
210
211 AliHLTConfiguration* AliHLTConfiguration::GetFirstSource()
212 {
213   // see header file for function documentation
214   AliHLTConfiguration* pSrc=NULL;
215   if (fNofSources>=0 || ExtractSources()>=0) {
216     fListSrcElement=fListSources.begin();
217     if (fListSrcElement!=fListSources.end()) pSrc=*fListSrcElement;
218   } 
219   return pSrc;
220 }
221
222 AliHLTConfiguration* AliHLTConfiguration::GetNextSource()
223 {
224   // see header file for function documentation
225   AliHLTConfiguration* pSrc=NULL;
226   if (fNofSources>0) {
227     if (fListSrcElement!=fListSources.end() && (++fListSrcElement)!=fListSources.end()) 
228       pSrc=*fListSrcElement;
229   } 
230   return pSrc;
231 }
232
233 int AliHLTConfiguration::SourcesResolved(int bAuto) 
234 {
235   // see header file for function documentation
236   int iResult=0;
237   if (fNofSources>=0 || (bAuto && (iResult=ExtractSources()))>=0) {
238     //HLTDebug("fNofSources=%d", fNofSources);
239     //HLTDebug("list size = %d", fListSources.size());
240     iResult=fNofSources==(int)fListSources.size();
241   }
242   return iResult;
243 }
244
245 int AliHLTConfiguration::InvalidateSource(AliHLTConfiguration* pConf)
246 {
247   // see header file for function documentation
248   int iResult=0;
249   if (pConf) {
250     vector<AliHLTConfiguration*>::iterator element=fListSources.begin();
251     while (element!=fListSources.end()) {
252       if (*element==pConf) {
253         fListSources.erase(element);
254         fListSrcElement=fListSources.end();
255         // there is no need to re-evaluate until there was a new configuration registered
256         // -> postpone the invalidation, its done in AliHLTConfigurationHandler::RegisterConfiguration
257         //InvalidateSources();
258         break;
259       }
260       element++;
261     }
262   } else {
263     iResult=-EINVAL;
264   }
265   return iResult;
266 }
267
268 void AliHLTConfiguration::PrintStatus()
269 {
270   // see header file for function documentation
271   HLTLogKeyword("configuration status");
272   HLTMessage("status of configuration \"%s\" (%p)", GetName(), this);
273   if (!fComponent.IsNull()) HLTMessage("  - component: \"%s\"", fComponent.Data());
274   else HLTMessage("  - component string invalid");
275   if (!fStringSources.IsNull()) HLTMessage("  - sources: \"%s\"", fStringSources.Data());
276   else HLTMessage("  - no sources");
277   if (SourcesResolved(1)<=0)
278     HLTMessage("    there are unresolved sources");
279   AliHLTConfiguration* pSrc=GetFirstSource();
280   while (pSrc) {
281     HLTMessage("    source \"%s\" (%p) resolved", pSrc->GetName(), pSrc);
282     pSrc=GetNextSource();
283   }
284 }
285
286 int AliHLTConfiguration::GetArguments(const char*** pArgv)
287 {
288   // see header file for function documentation
289   int iResult=0;
290   if (pArgv) {
291     if (fArgc==-1) {
292       if ((iResult=ExtractArguments())<0) {
293         HLTError("error extracting arguments for configuration %s", GetName());
294         fArgc=-EINVAL;
295       }
296     } else if (fArgc<0) {
297       HLTError("previous argument extraction failed");
298     }
299     //HLTDebug("%s fArgc %d", GetName(), fArgc);
300     iResult=fArgc;
301     *pArgv=(const char**)fArgv;
302   } else {
303     HLTError("invalid parameter");
304     iResult=-EINVAL;
305   }
306   return iResult;
307 }
308
309
310 int AliHLTConfiguration::ExtractSources()
311 {
312   // see header file for function documentation
313   int iResult=0;
314   fNofSources=0;
315   if (!fStringSources.IsNull()) {
316     vector<char*> tgtList;
317     fListSources.clear();
318     if ((iResult=InterpreteString(fStringSources.Data(), tgtList))>=0) {
319       fNofSources=tgtList.size();
320       vector<char*>::iterator element=tgtList.begin();
321       while ((element=tgtList.begin())!=tgtList.end()) {
322         if (fgConfigurationHandler) {
323           AliHLTConfiguration* pConf=fgConfigurationHandler->FindConfiguration(*element);
324           if (pConf) {
325             //HLTDebug("configuration %s (%p): source \"%s\" (%p) inserted", GetName(), this, pConf->GetName(), pConf);
326             fListSources.push_back(pConf);
327           } else {
328             HLTError("can not find source \"%s\"", (*element));
329             iResult=-ENOENT;
330           }
331         } else if (iResult>=0) {
332           iResult=-EFAULT;
333           HLTFatal("global configuration handler not initialized, can not resolve sources");
334         }
335         delete[] (*element);
336         tgtList.erase(element);
337       }
338       fListSrcElement=fListSources.begin();
339     }
340   }
341   return iResult;
342 }
343
344 int AliHLTConfiguration::ExtractArguments()
345 {
346   // see header file for function documentation
347   int iResult=0;
348   if (!fArguments.IsNull()) {
349     vector<char*> tgtList;
350     if ((iResult=InterpreteString(fArguments, tgtList))>=0) {
351       fArgc=tgtList.size();
352       //HLTDebug("configuration %s: extracted %d arguments from \"%s\"", GetName(), fArgc, fArguments);
353       if (fArgc>0) {
354         fArgv = new char*[fArgc];
355         if (fArgv) {
356           vector<char*>::iterator element=tgtList.begin();
357           int i=0;
358           while (element!=tgtList.end()) {
359             //HLTDebug("assign arguments %d (%s)", i, *element);
360             fArgv[i++]=(*element);
361             element++;
362           }
363         } else {
364           iResult=-ENOMEM;
365         }
366       }
367     }
368   } else {
369     // there are zero arguments
370     fArgc=0;
371   }
372   return iResult;
373 }
374
375 int AliHLTConfiguration::InterpreteString(const char* arg, vector<char*>& argList)
376 {
377   // see header file for function documentation
378   int iResult=0;
379   if (arg) {
380     //HLTDebug("interprete \"%s\"", arg);
381     int i=0;
382     int prec=-1;
383     int bQuote=0;
384     do {
385       //HLTDebug("%d %x", i, arg[i]);
386       if (arg[i]=='\'' && bQuote==0) {
387         bQuote=1;
388       } else if (arg[i]==0 || 
389                  (arg[i]==' ' && bQuote==0) ||
390                  (arg[i]=='\'' && bQuote==1)) {
391         bQuote=0;
392         if (prec>=0) {
393           char* pEntry= new char[i-prec+1];
394           if (pEntry) {
395             strncpy(pEntry, &arg[prec], i-prec);
396             pEntry[i-prec]=0; // terminate string
397             //HLTDebug("create string \"%s\", insert at %d", pEntry, argList.size());
398             argList.push_back(pEntry);
399           } else 
400             iResult=-ENOMEM;
401           prec=-1;
402         }
403       } else if (prec==-1) prec=i;
404     } while (arg[i++]!=0 && iResult>=0); 
405   } else {
406     iResult=-EINVAL;
407   }
408   return iResult;
409 }
410
411 int AliHLTConfiguration::ConvertSizeString(const char* strSize) const
412 {
413   // see header file for function documentation
414   int size=0;
415   if (!strSize) return -1;
416
417   char* endptr=NULL;
418   size=strtol(strSize, &endptr, 10);
419   if (size>=0) {
420     if (endptr) {
421       if (endptr==strSize) {
422         HLTWarning("ignoring unrecognized buffer size '%s'", strSize);
423         size=-1;
424       } else if (*endptr==0) {
425         // no unit specifier
426       } else if (*endptr=='k') {
427         size*=1014;
428       } else if (*endptr=='M') {
429         size*=1024*1024;
430       } else {
431         HLTWarning("ignoring buffer size of unknown unit '%c'", endptr[0]);
432       }
433     } else {
434       HLTWarning("ignoring negative buffer size specifier '%s'", strSize);
435       size=-1;
436     }
437   }
438   return size;
439 }
440
441 int AliHLTConfiguration::FollowDependency(const char* id, TList* pTgtList)
442 {
443   // see header file for function documentation
444   int iResult=0;
445   if (id) {
446     AliHLTConfiguration* pDep=NULL;
447     if ((pDep=GetSource(id))!=NULL) {
448       if (pTgtList) pTgtList->Add(pDep);
449       iResult++;
450     } else {
451       pDep=GetFirstSource();
452       while (pDep && iResult==0) {
453         if ((iResult=pDep->FollowDependency(id, pTgtList))>0) {
454           if (pTgtList) pTgtList->AddFirst(pDep);
455           iResult++;
456         }
457         pDep=GetNextSource();
458       }
459     }
460   } else {
461     iResult=-EINVAL;
462   }
463   return iResult;
464 }
465
466