Line data Source code
1 : // $Id$
2 :
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 AliHLTConfiguration.cxx
20 : /// @author Matthias Richter
21 : /// @date 2007
22 : /// @brief HLT configuration description for a single component.
23 : /// @note The class is used in Offline (AliRoot) context
24 :
25 : #include <cerrno>
26 : #include "AliHLTConfiguration.h"
27 : #include "AliHLTConfigurationHandler.h"
28 : #include "AliHLTTask.h"
29 : #include "AliHLTComponent.h"
30 : #include "AliHLTComponentHandler.h"
31 : #include <iostream>
32 : #include <string>
33 : #include "TList.h"
34 :
35 : using std::vector;
36 :
37 : /** ROOT macro for the implementation of ROOT specific class methods */
38 126 : ClassImp(AliHLTConfiguration)
39 :
40 0 : AliHLTConfiguration::AliHLTConfiguration()
41 : :
42 0 : fID(""),
43 0 : fComponent(""),
44 0 : fStringSources(""),
45 0 : fNofSources(-1),
46 0 : fListSources(),
47 0 : fListSrcElementIdx(-1),
48 0 : fArguments(""),
49 0 : fArgc(-1),
50 0 : fArgv(NULL),
51 0 : fBufferSize(-1)
52 0 : {
53 : // This class describes a configuration for an HLT component by means of
54 : // the following parameters:
55 : // - configuration id: a unique id string/name
56 : // - component id: id returned by AliHLTComponent::GetComponentID()
57 : // - parent configuartions: ids of configurations it requires input from
58 : // - component arguments: passed to the component when it is initialized
59 0 : }
60 :
61 0 : AliHLTConfiguration::AliHLTConfiguration(const char* id, const char* component, const char* sources,
62 : const char* arguments, const char* bufsize)
63 : :
64 0 : fID(id),
65 0 : fComponent(component),
66 0 : fStringSources(sources),
67 0 : fNofSources(-1),
68 0 : fListSources(),
69 0 : fListSrcElementIdx(-1),
70 0 : fArguments(arguments),
71 0 : fArgc(-1),
72 0 : fArgv(NULL),
73 0 : fBufferSize(-1)
74 0 : {
75 : // constructor
76 0 : if (bufsize) fBufferSize=ConvertSizeString(bufsize);
77 0 : if (id && component) {
78 0 : if (AliHLTConfigurationHandler::Instance()) {
79 0 : AliHLTConfigurationHandler::Instance()->RegisterConfiguration(this);
80 : } else {
81 0 : AliHLTConfigurationHandler::MissedRegistration(id);
82 : }
83 : }
84 0 : }
85 :
86 : AliHLTConfiguration::AliHLTConfiguration(const AliHLTConfiguration& src)
87 : :
88 0 : TObject(),
89 0 : AliHLTLogging(),
90 0 : fID(src.fID),
91 0 : fComponent(src.fComponent),
92 0 : fStringSources(src.fStringSources),
93 0 : fNofSources(-1),
94 0 : fListSources(),
95 0 : fListSrcElementIdx(-1),
96 0 : fArguments(src.fArguments),
97 0 : fArgc(-1),
98 0 : fArgv(NULL),
99 0 : fBufferSize(src.fBufferSize)
100 0 : {
101 : // copy constructor
102 0 : }
103 :
104 : AliHLTConfiguration& AliHLTConfiguration::operator=(const AliHLTConfiguration& src)
105 : {
106 : // assignment operator
107 0 : if (this==&src) return *this;
108 :
109 0 : fID=src.fID;
110 0 : fComponent=src.fComponent;
111 0 : fStringSources=src.fStringSources;
112 0 : fNofSources=-1;
113 0 : fArguments=src.fArguments;
114 0 : fArgc=-1;
115 0 : fArgv=NULL;
116 0 : fBufferSize=src.fBufferSize;
117 0 : return *this;
118 0 : }
119 :
120 0 : AliHLTConfiguration::~AliHLTConfiguration()
121 0 : {
122 : // destructor
123 0 : if (AliHLTConfigurationHandler::Instance()) {
124 0 : if (AliHLTConfigurationHandler::Instance()->FindConfiguration(fID.Data())!=NULL) {
125 : // remove the configuration from the handler if it exists
126 : // but DO NOT remove the clone configuration
127 0 : AliHLTConfigurationHandler::Instance()->RemoveConfiguration(this);
128 : }
129 : }
130 0 : if (fArgv != NULL) {
131 0 : if (fArgc>0) {
132 0 : for (int i=0; i<fArgc; i++) {
133 0 : delete[] fArgv[i];
134 : }
135 0 : }
136 0 : delete[] fArgv;
137 0 : fArgv=NULL;
138 0 : }
139 :
140 0 : vector<AliHLTConfiguration*>::iterator element=fListSources.begin();
141 0 : while (element!=fListSources.end()) {
142 0 : fListSources.erase(element);
143 0 : element=fListSources.begin();
144 : }
145 0 : }
146 :
147 : const char* AliHLTConfiguration::GetName() const
148 : {
149 : // get name
150 0 : if (!fID.IsNull())
151 0 : return fID.Data();
152 0 : return TObject::GetName();
153 0 : }
154 :
155 : AliHLTConfiguration* AliHLTConfiguration::GetSource(const char* id)
156 : {
157 : // get source by id
158 : AliHLTConfiguration* pSrc=NULL;
159 0 : if (id) {
160 : // first check the current element
161 0 : if (fListSrcElementIdx>=0 && fListSrcElementIdx<(int)fListSources.size() &&
162 0 : strcmp(id, (fListSources[fListSrcElementIdx])->GetName())==0) {
163 0 : pSrc=fListSources[fListSrcElementIdx];
164 0 : } else {
165 : // check the list
166 :
167 0 : pSrc=GetFirstSource();
168 0 : while (pSrc) {
169 0 : if (strcmp(id, pSrc->GetName())==0)
170 : break;
171 0 : pSrc=GetNextSource();
172 : }
173 : }
174 : }
175 0 : return pSrc;
176 : }
177 :
178 : AliHLTConfiguration* AliHLTConfiguration::GetFirstSource() const
179 : {
180 : // get first source in the list
181 : // TODO: iterator class
182 : AliHLTConfiguration* pSrc=NULL;
183 0 : if (fNofSources>0) {
184 0 : const_cast<AliHLTConfiguration*>(this)->fListSrcElementIdx=-1;
185 0 : pSrc=GetNextSource();
186 0 : }
187 0 : return pSrc;
188 : }
189 :
190 : AliHLTConfiguration* AliHLTConfiguration::GetNextSource() const
191 : {
192 : // get next source
193 : AliHLTConfiguration* pSrc=NULL;
194 0 : if (fNofSources>0) {
195 0 : if (fListSrcElementIdx+1<(int)fListSources.size()) {
196 0 : const_cast<AliHLTConfiguration*>(this)->fListSrcElementIdx++;
197 0 : pSrc=fListSources[fListSrcElementIdx];
198 0 : }
199 : }
200 0 : return pSrc;
201 : }
202 :
203 : int AliHLTConfiguration::SourcesResolved() const
204 : {
205 : // check if all sources are resolved
206 : int iResult=0;
207 0 : if (fNofSources>=0) {
208 0 : iResult=fNofSources==(int)fListSources.size();
209 0 : }
210 0 : return iResult;
211 : }
212 :
213 : int AliHLTConfiguration::InvalidateSource(AliHLTConfiguration* pConf)
214 : {
215 : // invalidate state of all sources
216 : int iResult=0;
217 0 : if (pConf) {
218 0 : vector<AliHLTConfiguration*>::iterator element=fListSources.begin();
219 0 : while (element!=fListSources.end()) {
220 0 : if (*element==pConf) {
221 0 : fListSources.erase(element);
222 0 : fListSrcElementIdx=fListSources.size();
223 : // there is no need to re-evaluate until there was a new configuration registered
224 : // -> postpone the invalidation, its done in AliHLTConfigurationHandler::RegisterConfiguration
225 : //InvalidateSources();
226 0 : break;
227 : }
228 0 : element++;
229 : }
230 0 : } else {
231 : iResult=-EINVAL;
232 : }
233 0 : return iResult;
234 : }
235 :
236 : void AliHLTConfiguration::PrintStatus() const
237 : {
238 : // print info
239 0 : HLTLogKeyword("configuration status");
240 0 : HLTMessage("status of configuration \"%s\" (%p)", GetName(), this);
241 0 : if (!fComponent.IsNull()) HLTMessage(" - component: \"%s\"", fComponent.Data());
242 0 : else HLTMessage(" - component string invalid");
243 0 : if (!fStringSources.IsNull()) HLTMessage(" - sources: \"%s\"", fStringSources.Data());
244 0 : else HLTMessage(" - no sources");
245 0 : if (SourcesResolved()!=1)
246 0 : HLTMessage(" there are unresolved sources");
247 0 : AliHLTConfiguration* pSrc=GetFirstSource();
248 0 : while (pSrc) {
249 0 : HLTMessage(" source \"%s\" (%p) resolved", pSrc->GetName(), pSrc);
250 0 : pSrc=GetNextSource();
251 : }
252 0 : }
253 :
254 : void AliHLTConfiguration::Print(const char* option) const
255 : {
256 : // print information
257 0 : if (option && strcmp(option, "status")==0) {
258 0 : PrintStatus();
259 0 : return;
260 : }
261 0 : HLTLogKeyword("configuration");
262 0 : HLTMessage("configuration %s: component %s, sources %s, arguments %s",
263 : GetName(),
264 : GetComponentID(),
265 : GetSourceSettings(),
266 : GetArgumentSettings()
267 : );
268 0 : }
269 :
270 : int AliHLTConfiguration::GetArguments(const char*** pArgv) const
271 : {
272 : // get argument array
273 : int iResult=0;
274 0 : if (pArgv) {
275 0 : if (fArgc==-1) {
276 0 : if ((iResult=const_cast<AliHLTConfiguration*>(this)->ExtractArguments())<0) {
277 0 : HLTError("error extracting arguments for configuration %s", GetName());
278 : }
279 0 : } else if (fArgc<0) {
280 0 : HLTError("previous argument extraction failed");
281 : }
282 : //HLTDebug("%s fArgc %d", GetName(), fArgc);
283 0 : iResult=fArgc;
284 0 : *pArgv=(const char**)fArgv;
285 0 : } else {
286 0 : HLTError("invalid parameter");
287 : iResult=-EINVAL;
288 : }
289 0 : return iResult;
290 : }
291 :
292 :
293 : int AliHLTConfiguration::ExtractSources(AliHLTConfigurationHandler* pHandler)
294 : {
295 : // extract source configurations from the handler
296 : // TODO: would be less confusing to use 'parent' instead of 'source'
297 : // but this needs to be changed consistently throughout the class
298 : int iResult=0;
299 0 : fNofSources=0; // indicates that the function was called, there are either n or 0 sources
300 0 : fListSources.clear();
301 0 : if (!pHandler) {
302 0 : HLTError("configuration handler missing, can not resolve sources");
303 0 : return -EFAULT;
304 : }
305 0 : if (!fStringSources.IsNull()) {
306 0 : vector<char*> tgtList;
307 0 : if ((iResult=InterpreteString(fStringSources.Data(), tgtList))>=0) {
308 0 : fNofSources=tgtList.size();
309 0 : vector<char*>::iterator element=tgtList.begin();
310 0 : while ((element=tgtList.begin())!=tgtList.end()) {
311 0 : AliHLTConfiguration* pConf=pHandler->FindConfiguration(*element);
312 0 : if (pConf) {
313 : //HLTDebug("configuration %s (%p): source \"%s\" (%p) inserted", GetName(), this, pConf->GetName(), pConf);
314 0 : fListSources.push_back(pConf);
315 : } else {
316 0 : HLTError("can not find source \"%s\"", (*element));
317 : iResult=-ENOENT;
318 : }
319 0 : delete[] (*element);
320 0 : tgtList.erase(element);
321 0 : }
322 0 : }
323 0 : }
324 0 : fListSrcElementIdx=-1;
325 0 : return iResult<0?iResult:SourcesResolved();
326 0 : }
327 :
328 : int AliHLTConfiguration::ExtractArguments()
329 : {
330 : // extract argument list from string
331 : int iResult=0;
332 0 : if (!fArguments.IsNull()) {
333 0 : vector<char*> tgtList;
334 0 : if ((iResult=InterpreteString(fArguments, tgtList))>=0) {
335 0 : fArgc=tgtList.size();
336 : //HLTDebug("configuration %s: extracted %d arguments from \"%s\"", GetName(), fArgc, fArguments);
337 0 : if (fArgc>0) {
338 0 : fArgv = new char*[fArgc];
339 0 : if (fArgv) {
340 0 : vector<char*>::iterator element=tgtList.begin();
341 : int i=0;
342 0 : while (element!=tgtList.end()) {
343 : //HLTDebug("assign arguments %d (%s)", i, *element);
344 0 : fArgv[i++]=(*element);
345 0 : element++;
346 : }
347 0 : } else {
348 : iResult=-ENOMEM;
349 : }
350 : }
351 : }
352 0 : } else {
353 : // there are zero arguments
354 0 : fArgc=0;
355 : }
356 0 : if (iResult<0) fArgc=iResult;
357 0 : return iResult;
358 0 : }
359 :
360 : int AliHLTConfiguration::InterpreteString(const char* arg, vector<char*>& argList)
361 : {
362 : // interprete a string
363 : int iResult=0;
364 0 : if (arg) {
365 : //HLTDebug("interprete \"%s\"", arg);
366 : int i=0;
367 : int prec=-1;
368 : int bQuote=0;
369 0 : do {
370 : //HLTDebug("%d %x", i, arg[i]);
371 0 : if (arg[i]=='\'' && bQuote==0) {
372 : bQuote=1;
373 0 : } else if (arg[i]==0 ||
374 0 : (arg[i]==' ' && bQuote==0) ||
375 0 : (arg[i]=='\'' && bQuote==1)) {
376 : bQuote=0;
377 0 : if (prec>=0) {
378 0 : char* pEntry= new char[i-prec+1];
379 0 : if (pEntry) {
380 0 : strncpy(pEntry, &arg[prec], i-prec);
381 0 : pEntry[i-prec]=0; // terminate string
382 : //HLTDebug("create string \"%s\", insert at %d", pEntry, argList.size());
383 0 : argList.push_back(pEntry);
384 0 : } else
385 : iResult=-ENOMEM;
386 : prec=-1;
387 0 : }
388 0 : } else if (prec==-1) prec=i;
389 0 : } while (arg[i++]!=0 && iResult>=0);
390 0 : } else {
391 : iResult=-EINVAL;
392 : }
393 0 : return iResult;
394 : }
395 :
396 : int AliHLTConfiguration::ConvertSizeString(const char* strSize) const
397 : {
398 : // convert a size argument
399 : int size=0;
400 0 : if (!strSize) return -1;
401 :
402 0 : char* endptr=NULL;
403 0 : size=strtol(strSize, &endptr, 10);
404 0 : if (size>=0) {
405 0 : if (endptr) {
406 0 : if (endptr==strSize) {
407 0 : HLTWarning("ignoring unrecognized buffer size '%s'", strSize);
408 : size=-1;
409 0 : } else if (*endptr==0) {
410 : // no unit specifier
411 0 : } else if (*endptr=='k') {
412 0 : size*=1014;
413 0 : } else if (*endptr=='M') {
414 0 : size*=1024*1024;
415 0 : } else {
416 0 : HLTWarning("ignoring buffer size of unknown unit '%c'", endptr[0]);
417 : }
418 : } else {
419 0 : HLTWarning("ignoring negative buffer size specifier '%s'", strSize);
420 : size=-1;
421 : }
422 : }
423 : return size;
424 0 : }
425 :
426 : int AliHLTConfiguration::FollowDependency(const char* id, TList* pTgtList)
427 : {
428 : // follow dependencies
429 : int iResult=0;
430 0 : if (id) {
431 : AliHLTConfiguration* pDep=NULL;
432 0 : if ((pDep=GetSource(id))!=NULL) {
433 0 : if (pTgtList) pTgtList->Add(pDep);
434 : iResult++;
435 0 : } else {
436 0 : pDep=GetFirstSource();
437 0 : while (pDep && iResult==0) {
438 0 : if ((iResult=pDep->FollowDependency(id, pTgtList))>0) {
439 0 : if (pTgtList) pTgtList->AddFirst(pDep);
440 0 : iResult++;
441 0 : }
442 0 : pDep=GetNextSource();
443 : }
444 : }
445 0 : } else {
446 : iResult=-EINVAL;
447 : }
448 0 : return iResult;
449 : }
450 :
451 :
|