Line data Source code
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 : //* Timm Steinbeck <timm@kip.uni-heidelberg.de> *
9 : //* for The ALICE HLT Project. *
10 : //* *
11 : //* Permission to use, copy, modify and distribute this software and its *
12 : //* documentation strictly for non-commercial purposes is hereby granted *
13 : //* without fee, provided that the above copyright notice appears in all *
14 : //* copies and that both the copyright notice and this permission notice *
15 : //* appear in the supporting documentation. The authors make no claims *
16 : //* about the suitability of this software for any purpose. It is *
17 : //* provided "as is" without express or implied warranty. *
18 : //**************************************************************************
19 :
20 : // @file AliHLTComponent.cxx
21 : // @author Matthias Richter, Timm Steinbeck
22 : // @date
23 : // @brief Base class implementation for HLT components. */
24 : // @note The class is both used in Online (PubSub) and Offline (AliRoot)
25 : // context
26 :
27 :
28 : //#include "AliHLTStdIncludes.h"
29 : #include "AliHLTComponent.h"
30 : #include "AliHLTComponentHandler.h"
31 : #include "AliHLTMessage.h"
32 : #include "AliHLTCTPData.h"
33 : #include "AliHLTErrorGuard.h"
34 : #include "AliHLTCDHWrapper.h"
35 : #include "TString.h"
36 : #include "TMath.h"
37 : #include "TObjArray.h"
38 : #include "TObjectTable.h"
39 : #include "TClass.h"
40 : #include "TStopwatch.h"
41 : #include "TFormula.h"
42 : #include "TUUID.h"
43 : #include "TMD5.h"
44 : #include "TRandom3.h"
45 : #include "AliHLTMemoryFile.h"
46 : #include "AliHLTMisc.h"
47 : #include "TTimeStamp.h"
48 : #include <cassert>
49 : #include <ctime>
50 : #include <stdint.h>
51 : #include "TStreamerInfo.h"
52 :
53 : #include <time.h>
54 : #include <sys/time.h>
55 : #include <map>
56 : #ifdef __MACH__
57 : #include <mach/clock.h>
58 : #include <mach/mach.h>
59 : #endif
60 :
61 : /**
62 : * default compression level for ROOT objects
63 : */
64 : #define ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION 5
65 : #define ALIHLTCOMPONENT_STATTIME_SCALER 1000000
66 :
67 : /** ROOT macro for the implementation of ROOT specific class methods */
68 126 : ClassImp(AliHLTComponent);
69 :
70 : /** stopwatch macro using the stopwatch guard */
71 : #define ALIHLTCOMPONENT_STOPWATCH(type) AliHLTStopwatchGuard swguard(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)type)):NULL)
72 : //#define ALIHLTCOMPONENT_STOPWATCH(type)
73 :
74 : /** stopwatch macro for operations of the base class */
75 : #define ALIHLTCOMPONENT_BASE_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWBase)
76 : /** stopwatch macro for operations of the detector algorithm (DA) */
77 : #define ALIHLTCOMPONENT_DA_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWDA)
78 :
79 348 : AliHLTComponent::AliHLTComponent()
80 : :
81 348 : fEnvironment(),
82 348 : fCurrentEvent(0),
83 348 : fEventCount(-1),
84 348 : fFailedEvents(0),
85 348 : fCurrentEventData(),
86 348 : fpInputBlocks(NULL),
87 348 : fCurrentInputBlock(-1),
88 348 : fSearchDataType(kAliHLTVoidDataType),
89 348 : fClassName(),
90 348 : fpInputObjects(NULL),
91 348 : fpOutputBuffer(NULL),
92 348 : fOutputBufferSize(0),
93 348 : fOutputBufferFilled(0),
94 348 : fOutputBlocks(),
95 1044 : fpStopwatches(new TObjArray(kSWTypeCount)),
96 348 : fMemFiles(),
97 348 : fpRunDesc(NULL),
98 348 : fCDBSetRunNoFunc(NULL),
99 348 : fChainId(),
100 348 : fChainIdCrc(0),
101 348 : fpBenchmark(NULL),
102 348 : fFlags(0),
103 348 : fEventType(gkAliEventTypeUnknown),
104 348 : fComponentArgs(),
105 348 : fEventDoneData(NULL),
106 348 : fEventDoneDataSize(0),
107 348 : fCompressionLevel(ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION)
108 348 : , fLastObjectSize(0)
109 348 : , fpCTPData(NULL)
110 348 : , fPushbackPeriod(0)
111 348 : , fLastPushBackTime(-1),
112 348 : fEventModulo(-1),
113 348 : fSchema(),
114 348 : fUseSchema(0),
115 348 : fSchemaUpdated(0)
116 1044 : {
117 : // see header file for class documentation
118 : // or
119 : // refer to README to build package
120 : // or
121 : // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
122 348 : memset(&fEnvironment, 0, sizeof(AliHLTAnalysisEnvironment));
123 348 : if (fgpComponentHandler)
124 15 : fgpComponentHandler->ScheduleRegister(this);
125 : //SetLocalLoggingLevel(kHLTLogDefault);
126 348 : }
127 :
128 : AliHLTComponent::~AliHLTComponent()
129 690 : {
130 : // see header file for function documentation
131 345 : if (fpBenchmark) delete fpBenchmark;
132 345 : fpBenchmark=NULL;
133 :
134 345 : CleanupInputObjects();
135 1035 : if (fpStopwatches!=NULL) delete fpStopwatches;
136 345 : fpStopwatches=NULL;
137 345 : AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
138 690 : while (element!=fMemFiles.end()) {
139 0 : if (*element) {
140 0 : if ((*element)->IsClosed()==0) {
141 0 : HLTWarning("memory file has not been closed, possible data loss or incomplete buffer");
142 : // close but do not flush as we dont know whether the buffer is still valid
143 0 : (*element)->CloseMemoryFile(0);
144 : }
145 0 : delete *element;
146 0 : *element=NULL;
147 0 : }
148 0 : element++;
149 : }
150 345 : if (fpRunDesc) {
151 0 : delete fpRunDesc;
152 0 : fpRunDesc=NULL;
153 0 : }
154 345 : if (fEventDoneData)
155 0 : delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
156 345 : fEventDoneData=NULL;
157 :
158 345 : if (fpCTPData) {
159 0 : delete fpCTPData;
160 : }
161 345 : fpCTPData=NULL;
162 345 : }
163 :
164 : AliHLTComponentHandler* AliHLTComponent::fgpComponentHandler=NULL;
165 :
166 : int AliHLTComponent::SetGlobalComponentHandler(AliHLTComponentHandler* pCH, int bOverwrite)
167 : {
168 : // see header file for function documentation
169 : int iResult=0;
170 168 : if (fgpComponentHandler==NULL || bOverwrite!=0)
171 84 : fgpComponentHandler=pCH;
172 : else
173 : iResult=-EPERM;
174 84 : return iResult;
175 : }
176 :
177 : int AliHLTComponent::UnsetGlobalComponentHandler()
178 : {
179 : // see header file for function documentation
180 84 : return SetGlobalComponentHandler(NULL,1);
181 : }
182 :
183 : int AliHLTComponent::SetComponentEnvironment(const AliHLTAnalysisEnvironment* comenv, void* environParam)
184 : {
185 : // see header file for function documentation
186 0 : HLTLogKeyword(fChainId.c_str());
187 : int iResult=0;
188 0 : if (comenv) {
189 0 : memset(&fEnvironment, 0, sizeof(AliHLTAnalysisEnvironment));
190 0 : memcpy(&fEnvironment, comenv, comenv->fStructSize<sizeof(AliHLTAnalysisEnvironment)?comenv->fStructSize:sizeof(AliHLTAnalysisEnvironment));
191 0 : fEnvironment.fStructSize=sizeof(AliHLTAnalysisEnvironment);
192 0 : fEnvironment.fParam=environParam;
193 0 : }
194 : return iResult;
195 0 : }
196 :
197 : int AliHLTComponent::Init(const AliHLTAnalysisEnvironment* comenv, void* environParam, int argc, const char** argv )
198 : {
199 : // see header file for function documentation
200 0 : HLTLogKeyword(fChainId.c_str());
201 : int iResult=0;
202 0 : if (comenv) {
203 0 : SetComponentEnvironment(comenv, environParam);
204 : }
205 0 : fPushbackPeriod=0;
206 0 : fLastPushBackTime=-1;
207 :
208 0 : fComponentArgs="";
209 : const char** pArguments=NULL;
210 : int iNofChildArgs=0;
211 0 : TString argument="";
212 : int bMissingParam=0;
213 0 : if (argc>0) {
214 0 : pArguments=new const char*[argc];
215 0 : if (pArguments) {
216 0 : for (int i=0; i<argc && iResult>=0; i++) {
217 0 : argument=argv[i];
218 0 : if (argument.IsNull()) continue;
219 :
220 : //reconstruct the argument string from argument array
221 0 : if (fComponentArgs.size()>0) fComponentArgs+=" ";
222 : //if an argument contains spaces it means it was single quoted
223 : //if quotes were removed - restore them
224 0 : if (argument.Contains(" ")) {
225 0 : if (!argument.Contains("'")) {
226 0 : fComponentArgs+="'";
227 0 : fComponentArgs+=argv[i];
228 0 : fComponentArgs+="'";
229 0 : } else if (!argument.EndsWith("'") ) {
230 : //**WORKAROUND:**
231 : //if a single quote exists with spaces after it means the
232 : //closing quote was removed - restore
233 0 : fComponentArgs+=argv[i];
234 0 : fComponentArgs+="'";
235 : }
236 : } else {
237 0 : fComponentArgs+=argv[i];
238 : }
239 :
240 : // benchmark
241 0 : if (argument.CompareTo("-benchmark")==0) {
242 :
243 : // -loglevel=
244 0 : } else if (argument.BeginsWith("-loglevel=")) {
245 0 : TString parameter=argument.ReplaceAll("-loglevel=", "");
246 0 : parameter.Remove(TString::kLeading, ' '); // remove all blanks
247 0 : if (parameter.BeginsWith("0x") &&
248 0 : parameter.Replace(0,2,"",0).IsHex()) {
249 0 : unsigned int loglevel=kHLTLogNone;
250 0 : sscanf(parameter.Data(),"%x", &loglevel);
251 0 : SetLocalLoggingLevel((AliHLTComponentLogSeverity)loglevel);
252 0 : } else {
253 0 : HLTError("wrong parameter for argument %s, hex number expected", argument.Data());
254 : iResult=-EINVAL;
255 : }
256 : // -object-compression=
257 0 : } else if (argument.BeginsWith("-object-compression=")) {
258 0 : argument.ReplaceAll("-object-compression=", "");
259 0 : if (argument.IsDigit()) {
260 0 : fCompressionLevel=argument.Atoi();
261 0 : if (fCompressionLevel<0 || fCompressionLevel>9) {
262 0 : HLTWarning("invalid compression level %d, setting to default %d", fCompressionLevel, ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION);
263 0 : fCompressionLevel=ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION;
264 0 : }
265 : } else {
266 0 : HLTError("wrong parameter for argument -object-compression, number expected");
267 : }
268 : // -pushback-period=
269 0 : } else if (argument.BeginsWith("-pushback-period=")) {
270 0 : argument.ReplaceAll("-pushback-period=", "");
271 0 : if (argument.IsDigit()) {
272 0 : fPushbackPeriod=argument.Atoi();
273 0 : } else {
274 0 : HLTError("wrong parameter for argument -pushback-period, number expected");
275 : }
276 : // -event-modulo
277 0 : } else if (argument.BeginsWith("-event-modulo=")) {
278 0 : argument.ReplaceAll("-event-modulo=", "");
279 0 : if (argument.IsDigit()) {
280 0 : fEventModulo=argument.Atoi();
281 0 : if (fEventModulo < 1)
282 : {
283 0 : fEventModulo = -1;
284 0 : HLTError("number passed in -event-modulo must be a positive integer greater or equal to 1.");
285 : }
286 : } else {
287 0 : HLTError("wrong parameter for argument -event-modulo, integer number expected");
288 : }
289 : // -disable-component-stat
290 0 : } else if (argument.CompareTo("-disable-component-stat")==0) {
291 0 : fFlags|=kDisableComponentStat;
292 0 : } else {
293 0 : pArguments[iNofChildArgs++]=argv[i];
294 : }
295 : }
296 0 : } else {
297 : iResult=-ENOMEM;
298 : }
299 : }
300 0 : if (bMissingParam) {
301 0 : HLTError("missing parameter for argument %s", argument.Data());
302 : iResult=-EINVAL;
303 0 : }
304 0 : if (iResult>=0) {
305 0 : iResult=CheckOCDBEntries();
306 0 : }
307 0 : if (iResult>=0) {
308 0 : iResult=DoInit(iNofChildArgs, pArguments);
309 0 : }
310 0 : if (iResult>=0) {
311 0 : fEventCount=0;
312 :
313 : // find out if the component wants to get the steering events
314 : // explicitly
315 0 : AliHLTComponentDataTypeList inputDt;
316 0 : GetInputDataTypes(inputDt);
317 : bool bRequireSteeringBlocks=false;
318 0 : for (AliHLTComponentDataTypeList::iterator dt=inputDt.begin();
319 0 : dt!=inputDt.end() && !bRequireSteeringBlocks;
320 0 : dt++) {
321 0 : bRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeSOR);
322 0 : bRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeRunType);
323 0 : bRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeEOR);
324 0 : bRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeDDL);
325 0 : bRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeComponentStatistics);
326 : }
327 0 : if (bRequireSteeringBlocks) fFlags|=kRequireSteeringBlocks;
328 0 : }
329 0 : if (pArguments) delete [] pArguments;
330 :
331 : #if defined(HLT_COMPONENT_STATISTICS)
332 : // benchmarking stopwatch for the component statistics
333 : fpBenchmark=new TStopwatch;
334 : #endif // HLT_COMPONENT_STATISTICS
335 :
336 : return iResult;
337 0 : }
338 :
339 : int AliHLTComponent::Deinit()
340 : {
341 : // see header file for function documentation
342 0 : HLTLogKeyword(fChainId.c_str());
343 : int iResult=0;
344 0 : iResult=DoDeinit();
345 0 : if (fpRunDesc) {
346 : // TODO: the warning should be kept, but the condition is wrong since the
347 : // AliHLTRunDesc is set before the SOR event in the SetRunDescription
348 : // method. A couple of state flags should be defined but that is a bit more
349 : // work to do. For the moment disable the warning (2009-07-01)
350 : // 2009-09-08: now, the info is not cleared in the ProcessEvent, because it
351 : // might be needed by components during the event processing.
352 : //HLTWarning("did not receive EOR for run %d", fpRunDesc->fRunNo);
353 : AliHLTRunDesc* pRunDesc=fpRunDesc;
354 0 : fpRunDesc=NULL;
355 0 : delete pRunDesc;
356 0 : }
357 0 : if (fpCTPData) {
358 0 : delete fpCTPData;
359 : }
360 0 : fpCTPData=NULL;
361 :
362 0 : fEventCount=0;
363 0 : fFlags=0;
364 : return iResult;
365 0 : }
366 :
367 : int AliHLTComponent::InitCDB(const char* cdbPath, AliHLTComponentHandler* pHandler)
368 : {
369 : // see header file for function documentation
370 : int iResult=0;
371 0 : HLTInfo("Using CDB: %s", cdbPath);
372 0 : if (pHandler) {
373 : // I have to think about separating the library handling from the
374 : // component handler. Requiring the component handler here is not
375 : // the cleanest solution.
376 : // We presume the library already to be loaded, which is the case
377 : // because it is loaded in the initialization of the logging functionality
378 : //
379 : // find the symbol
380 0 : AliHLTMiscInitCDB_t pFunc=(AliHLTMiscInitCDB_t)pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_INIT_CDB);
381 0 : if (pFunc) {
382 0 : TString path;
383 0 : if (cdbPath && cdbPath[0]!=0) {
384 0 : path=cdbPath;
385 : // very temporary fix, have to check for other formats
386 0 : if (!path.BeginsWith("local://")) {
387 0 : path="local://";
388 0 : path+=cdbPath;
389 : }
390 : }
391 0 : if ((iResult=(*pFunc)(path.Data()))>=0) {
392 0 : if (!(fCDBSetRunNoFunc=pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_SET_CDB_RUNNO))) {
393 0 : Message(NULL, kHLTLogWarning, "AliHLTComponent::InitCDB", "init CDB",
394 : "can not find function to set CDB run no");
395 : }
396 : }
397 0 : } else {
398 0 : Message(NULL, kHLTLogError, "AliHLTComponent::InitCDB", "init CDB",
399 : "can not find initialization function");
400 : iResult=-ENOSYS;
401 : }
402 0 : } else {
403 : iResult=-EINVAL;
404 : }
405 0 : return iResult;
406 0 : }
407 :
408 : int AliHLTComponent::SetCDBRunNo(int runNo)
409 : {
410 : // see header file for function documentation
411 0 : if (!fCDBSetRunNoFunc) return 0;
412 0 : return (*((AliHLTMiscSetCDBRunNo_t)fCDBSetRunNoFunc))(runNo);
413 0 : }
414 :
415 : int AliHLTComponent::SetRunDescription(const AliHLTRunDesc* desc, const char* /*runType*/)
416 : {
417 : // see header file for function documentation
418 0 : if (!desc) return -EINVAL;
419 0 : if (desc->fStructSize!=sizeof(AliHLTRunDesc)) {
420 0 : HLTError("invalid size of RunDesc struct (%ul)", desc->fStructSize);
421 0 : return -EINVAL;
422 : }
423 :
424 0 : if (!fpRunDesc) {
425 0 : fpRunDesc=new AliHLTRunDesc;
426 0 : if (!fpRunDesc) return -ENOMEM;
427 0 : *fpRunDesc=kAliHLTVoidRunDesc;
428 0 : }
429 :
430 0 : if (fpRunDesc->fRunNo!=kAliHLTVoidRunNo && fpRunDesc->fRunNo!=desc->fRunNo) {
431 0 : HLTWarning("Run description has already been set");
432 : }
433 0 : *fpRunDesc=*desc;
434 0 : SetCDBRunNo(fpRunDesc->fRunNo);
435 : // TODO: we have to decide about the runType
436 0 : return 0;
437 0 : }
438 :
439 : int AliHLTComponent::SetComponentDescription(const char* desc)
440 : {
441 : // see header file for function documentation
442 : int iResult=0;
443 0 : if (!desc) return 0;
444 :
445 0 : TString descriptor=desc;
446 0 : TObjArray* pTokens=descriptor.Tokenize(" ");
447 0 : if (pTokens) {
448 0 : for (int i=0; i<pTokens->GetEntriesFast() && iResult>=0; i++) {
449 0 : TString argument=pTokens->At(i++)->GetName();
450 0 : if (!argument || argument.IsNull()) continue;
451 :
452 : // chainid
453 0 : if (argument.BeginsWith("chainid")) {
454 0 : argument.ReplaceAll("chainid", "");
455 0 : if (argument.BeginsWith("=")) {
456 0 : fChainId=argument.Replace(0,1,"");
457 0 : fChainIdCrc=CalculateChecksum((const AliHLTUInt8_t*)fChainId.c_str(), fChainId.length());
458 : HLTDebug("setting component description: chain id %s crc 0x%8x", fChainId.c_str(), fChainIdCrc);
459 0 : } else {
460 0 : fChainId="";
461 : }
462 : } else {
463 0 : HLTWarning("unknown component description %s", argument.Data());
464 : }
465 0 : }
466 0 : delete pTokens;
467 : }
468 :
469 : return iResult;
470 0 : }
471 :
472 : int AliHLTComponent::ConfigureFromArgumentString(int argc, const char** argv)
473 : {
474 : // Configure from an array of argument strings
475 : // Function supports individual arguments in the argv array and arguments
476 : // separated by blanks.
477 : //
478 : // Each argv entry can contain blanks, quotes and newlines. Newlines are interpreted
479 : // as blanks. Enclosing quotes deactivate blank as delimiter.
480 : // The separated arguments are stored in an array of strings, and the pointers to
481 : // those strings in an array of pointers. The latter is used in the custom argument
482 : // scan of the component.
483 :
484 : int iResult=0;
485 0 : vector<string> stringarray; // array of argument copies
486 : // array of pointers to the argument copies
487 : // note: not necessarily in sync with the entries in stringarray
488 : // can contain any pointer to valid arguments in arbitrary sequence
489 0 : vector<const char*> ptrarray;
490 :
491 0 : TString argument="";
492 : int i=0;
493 0 : for (i=0; i<argc && iResult>=0; i++) {
494 0 : argument=argv[i];
495 0 : if (argument.IsWhitespace()) continue;
496 :
497 : // special handling for single component arguments ending with
498 : // a sequence of blanks. All characters until the first occurence
499 : // of a blank are removed. If the remainder contains only whitespaces
500 : // the argument is a single argument, just having whitespaces at the end.
501 0 : argument.Remove(0, argument.First(' '));
502 0 : if (argument.IsWhitespace()) {
503 0 : stringarray.push_back(argv[i]);
504 0 : continue;
505 : }
506 :
507 : // outer loop checks for enclosing quotes
508 : // extra blank to insert blank token before leading quotes, then
509 : // quoted arguments are always the even ones
510 0 : argument=" ";
511 0 : argument+=argv[i];
512 : // insert blank in consecutive quotes to correctly tokenize
513 0 : argument.ReplaceAll("''", "' '");
514 : // replace newlines by blanks
515 0 : argument.ReplaceAll("\n", " ");
516 0 : if (argument.IsNull()) continue;
517 0 : TObjArray* pTokensQuote=argument.Tokenize("'");
518 0 : if (pTokensQuote) {
519 0 : if (pTokensQuote->GetEntriesFast()>0) {
520 0 : for (int k=0; k<pTokensQuote->GetEntriesFast(); k++) {
521 0 : argument=pTokensQuote->At(k)->GetName();
522 0 : if (argument.IsWhitespace()) continue;
523 0 : if (k%2) {
524 : // every second entry is enclosed by quotes and thus
525 : // one single argument
526 0 : stringarray.push_back(argument.Data());
527 0 : } else {
528 0 : TObjArray* pTokens=argument.Tokenize(" ");
529 0 : if (pTokens) {
530 0 : if (pTokens->GetEntriesFast()>0) {
531 0 : for (int n=0; n<pTokens->GetEntriesFast(); n++) {
532 0 : TString data=pTokens->At(n)->GetName();
533 0 : if (!data.IsNull() && !data.IsWhitespace()) {
534 0 : stringarray.push_back(data.Data());
535 0 : }
536 0 : }
537 0 : }
538 0 : delete pTokens;
539 : }
540 : }
541 : }
542 0 : }
543 0 : delete pTokensQuote;
544 : }
545 0 : }
546 :
547 : // fill ptrarray; should be safe at this point
548 : // since stringarray isn't modified any further
549 : unsigned int idx;
550 0 : for(idx=0; idx<stringarray.size(); ++idx) {
551 0 : ptrarray.push_back(stringarray.at(idx).c_str());
552 : }
553 :
554 0 : for (i=0; (unsigned)i<ptrarray.size() && iResult>=0;) {
555 0 : int result=ScanConfigurationArgument(ptrarray.size()-i, &ptrarray[i]);
556 0 : if (result==0) {
557 0 : HLTWarning("unknown component argument %s", ptrarray[i]);
558 0 : i++;
559 0 : } else if (result>0) {
560 0 : i+=result;
561 0 : } else {
562 : iResult=result;
563 0 : if (iResult==-EINVAL) {
564 0 : HLTError("unknown argument %s", ptrarray[i]);
565 0 : } else if (iResult==-EPROTO) {
566 0 : HLTError("missing/wrong parameter for argument %s (%s)", ptrarray[i], (ptrarray.size()>(unsigned)i+1)?ptrarray[i+1]:"missing");
567 : } else {
568 0 : HLTError("scan of argument %s failed (%d)", ptrarray[i], iResult);
569 : }
570 : }
571 : }
572 :
573 : return iResult;
574 0 : }
575 :
576 : int AliHLTComponent::ConfigureFromCDBTObjString(const char* entries, const char* key, bool defaultToEmptyString)
577 : {
578 : // load a list of OCDB objects and configure from the objects
579 : // can either be a TObjString or a TMap with a TObjString:TObjString key-value pair
580 : int iResult=0;
581 0 : TString arguments;
582 0 : TString confEntries=entries;
583 0 : TObjArray* pTokens=confEntries.Tokenize(" ");
584 0 : if (pTokens) {
585 0 : for (int n=0; n<pTokens->GetEntriesFast(); n++) {
586 0 : const char* path=pTokens->At(n)->GetName();
587 0 : const char* chainId=GetChainId();
588 0 : HLTInfo("configure from entry \"%s\"%s%s, chain id %s", path, key?" key ":"",key?key:"", (chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
589 0 : TObject* pOCDBObject = LoadAndExtractOCDBObject(path, key);
590 0 : if (pOCDBObject) {
591 0 : TObjString* pString=dynamic_cast<TObjString*>(pOCDBObject);
592 0 : if (!pString) {
593 0 : TMap* pMap=dynamic_cast<TMap*>(pOCDBObject);
594 0 : if (pMap) {
595 : // this is the case where no key has been specified and the OCDB
596 : // object is a TMap, search for the default key
597 0 : TObject* pObject=pMap->GetValue("default");
598 0 : if (pObject && (pString=dynamic_cast<TObjString*>(pObject))!=NULL) {
599 0 : HLTInfo("using default key of TMap of configuration object \"%s\"", path);
600 : } else {
601 0 : HLTError("no default key available in TMap of configuration object \"%s\"", path);
602 : iResult=-ENOENT;
603 0 : break;
604 : }
605 0 : }
606 0 : }
607 :
608 0 : if (pString) {
609 0 : HLTInfo("received configuration object string: \'%s\'", pString->GetName());
610 0 : if( !arguments.IsNull() ) arguments+=" ";
611 0 : arguments+=pString->GetName();
612 : } else {
613 0 : HLTError("configuration object \"%s\"%s%s has wrong type, required TObjString", path, key?" key ":"",key?key:"");
614 : iResult=-EINVAL;
615 : }
616 0 : } else {
617 0 : HLTError("can not fetch object \"%s\" from OCDB", path);
618 0 : if (defaultToEmptyString)
619 : {
620 0 : arguments = "";
621 : }
622 : else
623 : {
624 : iResult=-ENOENT;
625 : }
626 : }
627 0 : }
628 0 : delete pTokens;
629 : }
630 0 : if (iResult>=0 && !arguments.IsNull()) {
631 0 : const char* array=arguments.Data();
632 0 : iResult=ConfigureFromArgumentString(1, &array);
633 0 : }
634 : return iResult;
635 0 : }
636 :
637 : TObject* AliHLTComponent::LoadAndExtractOCDBObject(const char* path, const char* key) const
638 : {
639 : // see header file for function documentation
640 0 : AliCDBEntry* pEntry=AliHLTMisc::Instance().LoadOCDBEntry(path, GetRunNo());
641 0 : if (!pEntry) return NULL;
642 0 : TObject* pObject=AliHLTMisc::Instance().ExtractObject(pEntry);
643 0 : TMap* pMap=dynamic_cast<TMap*>(pObject);
644 0 : if (pMap && key) {
645 0 : pObject=pMap->GetValue(key);
646 0 : if (!pObject) {
647 0 : pObject=pMap->GetValue("default");
648 0 : if (pObject) {
649 0 : HLTWarning("can not find object for key \"%s\" in TMap of configuration object \"%s\", using key \"default\"", key, path);
650 : }
651 : }
652 0 : if (!pObject) {
653 0 : HLTError("can not find object for key \"%s\" in TMap of configuration object \"%s\"", key, path);
654 0 : return NULL;
655 : }
656 : }
657 0 : return pObject;
658 0 : }
659 :
660 : int AliHLTComponent::DoInit( int /*argc*/, const char** /*argv*/)
661 : {
662 : // default implementation, childs can overload
663 0 : HLTLogKeyword("dummy");
664 : return 0;
665 0 : }
666 :
667 : int AliHLTComponent::DoDeinit()
668 : {
669 : // default implementation, childs can overload
670 0 : HLTLogKeyword("dummy");
671 : return 0;
672 0 : }
673 :
674 : int AliHLTComponent::Reconfigure(const char* /*cdbEntry*/, const char* /*chainId*/)
675 : {
676 : // default implementation, childs can overload
677 0 : HLTLogKeyword("dummy");
678 : return 0;
679 0 : }
680 :
681 : int AliHLTComponent::ReadPreprocessorValues(const char* /*modules*/)
682 : {
683 : // default implementation, childs can overload
684 0 : HLTLogKeyword("dummy");
685 : return 0;
686 0 : }
687 :
688 : int AliHLTComponent::ScanConfigurationArgument(int /*argc*/, const char** /*argv*/)
689 : {
690 : // default implementation, childs can overload
691 0 : HLTLogKeyword("dummy");
692 0 : HLTWarning("The function needs to be implemented by the component");
693 : return 0;
694 0 : }
695 :
696 : int AliHLTComponent::StartOfRun()
697 : {
698 : // default implementation, childs can overload
699 0 : HLTLogKeyword("dummy");
700 : return 0;
701 0 : }
702 :
703 : int AliHLTComponent::EndOfRun()
704 : {
705 : // default implementation, childs can overload
706 0 : HLTLogKeyword("dummy");
707 : return 0;
708 0 : }
709 :
710 :
711 : int AliHLTComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& /*tgtList*/)
712 : {
713 : // default implementation, childs can overload
714 0 : HLTLogKeyword("dummy");
715 : return 0;
716 0 : }
717 :
718 : void AliHLTComponent::GetOCDBObjectDescription( TMap* const /*targetArray*/)
719 : {
720 : // default implementation, childs can overload
721 0 : HLTLogKeyword("dummy");
722 0 : }
723 :
724 : int AliHLTComponent::CheckOCDBEntries(const TMap* const externList)
725 : {
726 : // check the availability of the OCDB entry descriptions in the TMap
727 : // key : complete OCDB path of the entry
728 : // value : auxiliary object - short description
729 : // if the external map was not provided the function invokes
730 : // interface function GetOCDBObjectDescription() to retrieve the list.
731 : int iResult=0;
732 0 : if (externList) {
733 0 : iResult=AliHLTMisc::Instance().CheckOCDBEntries(externList);
734 0 : } else {
735 0 : TMap* pMap=new TMap;
736 0 : if (pMap) {
737 0 : pMap->SetOwnerKeyValue(kTRUE);
738 0 : GetOCDBObjectDescription(pMap);
739 0 : iResult=AliHLTMisc::Instance().CheckOCDBEntries(pMap);
740 0 : delete pMap;
741 : pMap=NULL;
742 0 : }
743 : }
744 :
745 0 : return iResult;
746 0 : }
747 :
748 : void AliHLTComponent::DataType2Topic( const AliHLTComponentDataType type,
749 : char *output )
750 : {
751 : // this produces a fixed length string, first 8 chars are the data type id, 4 last are origin
752 : // so for
753 : //memset( output, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize );
754 0 : memcpy( output, type.fID, kAliHLTComponentDataTypefIDsize );
755 0 : memcpy( output+kAliHLTComponentDataTypefIDsize, type.fOrigin, kAliHLTComponentDataTypefOriginSize );
756 0 : }
757 :
758 : void AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, char output[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2] ) const
759 : {
760 : // see header file for function documentation
761 0 : memset( output, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
762 0 : strncat( output, type.fOrigin, kAliHLTComponentDataTypefOriginSize );
763 0 : strncat( output, ":", 1 );
764 0 : strncat( output, type.fID, kAliHLTComponentDataTypefIDsize );
765 0 : }
766 :
767 : string AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, int mode)
768 : {
769 : // see header file for function documentation
770 0 : string out("");
771 :
772 : // 'typeid' 'origin'
773 : // aligned to 8 and 4 chars respectively, blocks enclosed in quotes and
774 : // separated by blank e.g.
775 : // 'DDL_RAW ' 'TPC '
776 0 : if (mode==3) {
777 : int i=0;
778 0 : char tmp[8];
779 0 : out+="'";
780 0 : for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
781 0 : unsigned char* puc=(unsigned char*)type.fID;
782 0 : if (puc[i]<32)
783 0 : sprintf(tmp, "\\%x", type.fID[i]);
784 : else
785 0 : sprintf(tmp, "%c", type.fID[i]);
786 0 : out+=tmp;
787 : }
788 0 : out+="' '";
789 0 : for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
790 0 : unsigned char* puc=(unsigned char*)type.fOrigin;
791 0 : if ((puc[i])<32)
792 0 : sprintf(tmp, "\\%x", type.fOrigin[i]);
793 : else
794 0 : sprintf(tmp, "%c", type.fOrigin[i]);
795 0 : out+=tmp;
796 : }
797 0 : out+="'";
798 : return out;
799 0 : }
800 :
801 : // origin typeid as numbers separated by colon e.g.
802 : // aligned to 8 and 4 chars respectively, all characters separated by
803 : // quotes, e.g.
804 : // '84'80'67'32':'68'68'76'95'82'65'87'32'
805 0 : if (mode==2) {
806 : int i=0;
807 0 : char tmp[8];
808 0 : for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
809 0 : sprintf(tmp, "'%d", type.fOrigin[i]);
810 0 : out+=tmp;
811 : }
812 0 : out+="':'";
813 0 : for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
814 0 : sprintf(tmp, "%d'", type.fID[i]);
815 0 : out+=tmp;
816 : }
817 : return out;
818 0 : }
819 :
820 : // origin typeid separated by colon e.g.
821 : // aligned to 8 and 4 chars respectively, all characters separated by
822 : // quotes, e.g.
823 : // 'T'P'C' ':'D'D'L'_'R'A'W' '
824 0 : if (mode==1) {
825 : int i=0;
826 0 : char tmp[8];
827 0 : for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
828 0 : unsigned char* puc=(unsigned char*)type.fOrigin;
829 0 : if ((puc[i])<32)
830 0 : sprintf(tmp, "'\\%x", type.fOrigin[i]);
831 : else
832 0 : sprintf(tmp, "'%c", type.fOrigin[i]);
833 0 : out+=tmp;
834 : }
835 0 : out+="':'";
836 0 : for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
837 0 : unsigned char* puc=(unsigned char*)type.fID;
838 0 : if (puc[i]<32)
839 0 : sprintf(tmp, "\\%x'", type.fID[i]);
840 : else
841 0 : sprintf(tmp, "%c'", type.fID[i]);
842 0 : out+=tmp;
843 : }
844 : return out;
845 0 : }
846 :
847 : // origin typeid
848 : // aligned to 8 and 4 chars respectively, separated by colon e.g.
849 : // TPC :DDL_RAW
850 0 : if (type==kAliHLTVoidDataType) {
851 0 : out="VOID:VOID";
852 : } else {
853 : // some gymnastics in order to avoid a '0' which is part of either or both
854 : // ID and origin terminating the whole string. Unfortunately, string doesn't
855 : // stop appending at the '0' if the number of elements to append was
856 : // explicitely specified
857 0 : string tmp("");
858 0 : tmp.append(type.fOrigin, kAliHLTComponentDataTypefOriginSize);
859 0 : out.append(tmp.c_str());
860 0 : out.append(":");
861 0 : tmp="";
862 0 : tmp.append(type.fID, kAliHLTComponentDataTypefIDsize);
863 0 : out.append(tmp.c_str());
864 0 : }
865 0 : return out;
866 0 : }
867 :
868 :
869 : void* AliHLTComponent::AllocMemory( unsigned long size )
870 : {
871 : // see header file for function documentation
872 0 : if (fEnvironment.fAllocMemoryFunc)
873 0 : return (*fEnvironment.fAllocMemoryFunc)(fEnvironment.fParam, size );
874 0 : HLTFatal("no memory allocation handler registered");
875 0 : return NULL;
876 0 : }
877 :
878 : int AliHLTComponent::MakeOutputDataBlockList( const AliHLTComponentBlockDataList& blocks, AliHLTUInt32_t* blockCount,
879 : AliHLTComponentBlockData** outputBlocks )
880 : {
881 : // see header file for function documentation
882 0 : if ( blockCount==NULL || outputBlocks==NULL )
883 0 : return -EFAULT;
884 0 : AliHLTUInt32_t count = blocks.size();
885 0 : if ( !count )
886 : {
887 0 : *blockCount = 0;
888 0 : *outputBlocks = NULL;
889 0 : return 0;
890 : }
891 0 : *outputBlocks = reinterpret_cast<AliHLTComponentBlockData*>( AllocMemory( sizeof(AliHLTComponentBlockData)*count ) );
892 0 : if ( !*outputBlocks )
893 0 : return -ENOMEM;
894 0 : for ( unsigned long i = 0; i < count; i++ ) {
895 0 : (*outputBlocks)[i] = blocks[i];
896 0 : if (MatchExactly(blocks[i].fDataType, kAliHLTAnyDataType)) {
897 0 : (*outputBlocks)[i].fDataType=GetOutputDataType();
898 : /* data type was set to the output data type by the PubSub AliRoot
899 : Wrapper component, if data type of the block was ********:****.
900 : Now handled by the component base class in order to have same
901 : behavior when running embedded in AliRoot
902 : memset((*outputBlocks)[i].fDataType.fID, '*', kAliHLTComponentDataTypefIDsize);
903 : memset((*outputBlocks)[i].fDataType.fOrigin, '*', kAliHLTComponentDataTypefOriginSize);
904 : */
905 0 : }
906 : }
907 0 : *blockCount = count;
908 0 : return 0;
909 :
910 0 : }
911 :
912 : int AliHLTComponent::GetEventDoneData( unsigned long size, AliHLTComponentEventDoneData** edd ) const
913 : {
914 : // see header file for function documentation
915 0 : if (fEnvironment.fGetEventDoneDataFunc)
916 0 : return (*fEnvironment.fGetEventDoneDataFunc)(fEnvironment.fParam, fCurrentEvent, size, edd );
917 0 : return -ENOSYS;
918 0 : }
919 :
920 : int AliHLTComponent::ReserveEventDoneData( unsigned long size )
921 : {
922 : // see header file for function documentation
923 : int iResult=0;
924 :
925 0 : unsigned long capacity=fEventDoneDataSize;
926 0 : if (fEventDoneData) capacity-=sizeof(AliHLTComponentEventDoneData)+fEventDoneData->fDataSize;
927 0 : if (size>capacity) {
928 0 : unsigned long newSize=sizeof(AliHLTComponentEventDoneData)+size+(fEventDoneDataSize-capacity);
929 0 : AliHLTComponentEventDoneData* newEDD = reinterpret_cast<AliHLTComponentEventDoneData*>( new AliHLTUInt8_t[newSize] );
930 0 : if (!newEDD)
931 0 : return -ENOMEM;
932 0 : newEDD->fStructSize = sizeof(AliHLTComponentEventDoneData);
933 0 : newEDD->fDataSize = 0;
934 0 : newEDD->fData = reinterpret_cast<AliHLTUInt8_t*>(newEDD)+newEDD->fStructSize;
935 0 : if (fEventDoneData) {
936 0 : memcpy( newEDD->fData, fEventDoneData->fData, fEventDoneData->fDataSize );
937 0 : newEDD->fDataSize = fEventDoneData->fDataSize;
938 0 : delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
939 : }
940 0 : fEventDoneData = newEDD;
941 0 : fEventDoneDataSize = newSize;
942 0 : }
943 0 : return iResult;
944 :
945 0 : }
946 :
947 : int AliHLTComponent::PushEventDoneData( AliHLTUInt32_t eddDataWord )
948 : {
949 : // see header file for function documentation
950 0 : if (!fEventDoneData)
951 0 : return -ENOMEM;
952 0 : if (fEventDoneData->fDataSize+sizeof(AliHLTUInt32_t)>fEventDoneDataSize)
953 0 : return -ENOSPC;
954 0 : *reinterpret_cast<AliHLTUInt32_t*>((reinterpret_cast<AliHLTUInt8_t*>(fEventDoneData->fData)+fEventDoneData->fDataSize)) = eddDataWord;
955 0 : fEventDoneData->fDataSize += sizeof(AliHLTUInt32_t);
956 0 : return 0;
957 0 : }
958 :
959 : void AliHLTComponent::ReleaseEventDoneData()
960 : {
961 : // see header file for function documentation
962 0 : if (fEventDoneData)
963 0 : delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
964 0 : fEventDoneData = NULL;
965 0 : fEventDoneDataSize = 0;
966 0 : }
967 :
968 :
969 : int AliHLTComponent::FindMatchingDataTypes(AliHLTComponent* pConsumer, AliHLTComponentDataTypeList* tgtList)
970 : {
971 : // see header file for function documentation
972 : int iResult=0;
973 0 : if (pConsumer) {
974 0 : AliHLTComponentDataTypeList itypes;
975 0 : AliHLTComponentDataTypeList otypes;
976 0 : otypes.push_back(GetOutputDataType());
977 0 : if (MatchExactly(otypes[0],kAliHLTMultipleDataType)) {
978 0 : otypes.clear();
979 : int count=0;
980 0 : if ((count=GetOutputDataTypes(otypes))>0) {
981 0 : } else if (GetComponentType()!=kSink) {
982 0 : HLTWarning("component %s indicates multiple output data types but GetOutputDataTypes returns %d", GetComponentID(), count);
983 : }
984 0 : }
985 0 : pConsumer->GetInputDataTypes(itypes);
986 0 : AliHLTComponentDataTypeList::iterator otype=otypes.begin();
987 0 : for (;otype!=otypes.end();otype++) {
988 : //PrintDataTypeContent((*otype), "publisher \'%s\'");
989 0 : if ((*otype)==(kAliHLTAnyDataType|kAliHLTDataOriginPrivate)) {
990 0 : if (tgtList) tgtList->push_back(*otype);
991 0 : iResult++;
992 0 : continue;
993 : }
994 :
995 0 : AliHLTComponentDataTypeList::iterator itype=itypes.begin();
996 0 : for ( ; itype!=itypes.end() && (*itype)!=(*otype) ; itype++) {/* empty body */};
997 : //if (itype!=itypes.end()) PrintDataTypeContent(*itype, "consumer \'%s\'");
998 0 : if (itype!=itypes.end()) {
999 0 : if (tgtList) tgtList->push_back(*otype);
1000 0 : iResult++;
1001 0 : }
1002 0 : }
1003 0 : } else {
1004 : iResult=-EINVAL;
1005 : }
1006 0 : return iResult;
1007 0 : }
1008 :
1009 : void AliHLTComponent::PrintDataTypeContent(AliHLTComponentDataType& dt, const char* format)
1010 : {
1011 : // see header file for function documentation
1012 : const char* fmt="\'%s\'";
1013 0 : if (format) fmt=format;
1014 0 : AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, Form(fmt, (DataType2Text(dt)).c_str()));
1015 0 : AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL,
1016 0 : Form("%x %x %x %x %x %x %x %x : %x %x %x %x",
1017 0 : dt.fID[0],
1018 0 : dt.fID[1],
1019 0 : dt.fID[2],
1020 0 : dt.fID[3],
1021 0 : dt.fID[4],
1022 0 : dt.fID[5],
1023 0 : dt.fID[6],
1024 0 : dt.fID[7],
1025 0 : dt.fOrigin[0],
1026 0 : dt.fOrigin[1],
1027 0 : dt.fOrigin[2],
1028 0 : dt.fOrigin[3]));
1029 0 : }
1030 :
1031 : void AliHLTComponent::FillBlockData( AliHLTComponentBlockData& blockData )
1032 : {
1033 : // see header file for function documentation
1034 0 : blockData.fStructSize = sizeof(blockData);
1035 0 : FillShmData( blockData.fShmKey );
1036 0 : blockData.fOffset = ~(AliHLTUInt32_t)0;
1037 0 : blockData.fPtr = NULL;
1038 0 : blockData.fSize = 0;
1039 0 : FillDataType( blockData.fDataType );
1040 0 : blockData.fSpecification = kAliHLTVoidDataSpec;
1041 0 : }
1042 :
1043 : void AliHLTComponent::FillShmData( AliHLTComponentShmData& shmData )
1044 : {
1045 : // see header file for function documentation
1046 0 : shmData.fStructSize = sizeof(shmData);
1047 0 : shmData.fShmType = gkAliHLTComponentInvalidShmType;
1048 0 : shmData.fShmID = gkAliHLTComponentInvalidShmID;
1049 0 : }
1050 :
1051 : void AliHLTComponent::FillDataType( AliHLTComponentDataType& dataType )
1052 : {
1053 : // see header file for function documentation
1054 0 : dataType=kAliHLTAnyDataType;
1055 0 : }
1056 :
1057 : void AliHLTComponent::CopyDataType(AliHLTComponentDataType& tgtdt, const AliHLTComponentDataType& srcdt)
1058 : {
1059 : // see header file for function documentation
1060 0 : memcpy(&tgtdt.fID[0], &srcdt.fID[0], kAliHLTComponentDataTypefIDsize);
1061 0 : memcpy(&tgtdt.fOrigin[0], &srcdt.fOrigin[0], kAliHLTComponentDataTypefOriginSize);
1062 0 : }
1063 :
1064 : void AliHLTComponent::SetDataType(AliHLTComponentDataType& tgtdt, const char* id, const char* origin)
1065 : {
1066 : // see header file for function documentation
1067 0 : tgtdt.fStructSize=sizeof(AliHLTComponentDataType);
1068 0 : if (id) {
1069 0 : memset(&tgtdt.fID[0], 0, kAliHLTComponentDataTypefIDsize);
1070 0 : strncpy(&tgtdt.fID[0], id, strlen(id)<(size_t)kAliHLTComponentDataTypefIDsize?strlen(id):kAliHLTComponentDataTypefIDsize);
1071 0 : }
1072 0 : if (origin) {
1073 0 : memset(&tgtdt.fOrigin[0], 0, kAliHLTComponentDataTypefOriginSize);
1074 0 : strncpy(&tgtdt.fOrigin[0], origin, strlen(origin)<(size_t)kAliHLTComponentDataTypefOriginSize?strlen(origin):kAliHLTComponentDataTypefOriginSize);
1075 0 : }
1076 0 : }
1077 :
1078 : void AliHLTComponent::SetDataType(AliHLTComponentDataType& dt, AliHLTUInt64_t id, AliHLTUInt32_t origin)
1079 : {
1080 : // see header file for function documentation
1081 0 : dt.fStructSize=sizeof(AliHLTComponentDataType);
1082 : assert(kAliHLTComponentDataTypefIDsize==sizeof(id));
1083 : assert(kAliHLTComponentDataTypefOriginSize==sizeof(origin));
1084 0 : memcpy(&dt.fID, &id, kAliHLTComponentDataTypefIDsize);
1085 0 : memcpy(&dt.fOrigin, &origin, kAliHLTComponentDataTypefOriginSize);
1086 0 : }
1087 :
1088 : void AliHLTComponent::FillEventData(AliHLTComponentEventData& evtData)
1089 : {
1090 : // see header file for function documentation
1091 0 : memset(&evtData, 0, sizeof(AliHLTComponentEventData));
1092 0 : evtData.fStructSize=sizeof(AliHLTComponentEventData);
1093 0 : evtData.fEventID=kAliHLTVoidEventID;
1094 0 : evtData.fEventCreation_s = kMaxUInt;
1095 0 : }
1096 :
1097 : void AliHLTComponent::PrintComponentDataTypeInfo(const AliHLTComponentDataType& dt)
1098 : {
1099 : // see header file for function documentation
1100 0 : TString msg;
1101 0 : msg.Form("AliHLTComponentDataType(%d): ID=\"", dt.fStructSize);
1102 0 : for ( int i = 0; i < kAliHLTComponentDataTypefIDsize; i++ ) {
1103 0 : if (dt.fID[i]!=0) msg+=dt.fID[i];
1104 0 : else msg+="\\0";
1105 : }
1106 0 : msg+="\" Origin=\"";
1107 0 : for ( int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++ ) {
1108 0 : if (dt.fOrigin[i]!=0) msg+=dt.fOrigin[i];
1109 0 : else msg+="\\0";
1110 : }
1111 0 : msg+="\"";
1112 0 : AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, msg.Data());
1113 0 : }
1114 :
1115 : int AliHLTComponent::GetEventCount() const
1116 : {
1117 : // see header file for function documentation
1118 0 : return fEventCount;
1119 : }
1120 :
1121 : int AliHLTComponent::IncrementEventCounter()
1122 : {
1123 : // see header file for function documentation
1124 0 : if (fEventCount>=0) fEventCount++;
1125 0 : return fEventCount;
1126 : }
1127 :
1128 : int AliHLTComponent::GetNumberOfInputBlocks() const
1129 : {
1130 : // see header file for function documentation
1131 0 : if (fpInputBlocks!=NULL) {
1132 0 : return fCurrentEventData.fBlockCnt;
1133 : }
1134 0 : return 0;
1135 0 : }
1136 :
1137 : AliHLTEventID_t AliHLTComponent::GetEventId() const
1138 : {
1139 : // see header file for function documentation
1140 0 : if (fpInputBlocks!=NULL) {
1141 0 : return fCurrentEventData.fEventID;
1142 : }
1143 0 : return 0;
1144 0 : }
1145 :
1146 : const TObject* AliHLTComponent::GetFirstInputObject(const AliHLTComponentDataType& dt,
1147 : const char* classname,
1148 : int bForce)
1149 : {
1150 : // see header file for function documentation
1151 0 : ALIHLTCOMPONENT_BASE_STOPWATCH();
1152 0 : fSearchDataType=dt;
1153 0 : if (classname) fClassName=classname;
1154 0 : else fClassName.clear();
1155 0 : int idx=FindInputBlock(fSearchDataType, 0, 1);
1156 : TObject* pObj=NULL;
1157 0 : if (idx>=0) {
1158 : HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(dt).c_str());
1159 0 : if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
1160 0 : fCurrentInputBlock=idx;
1161 0 : } else {
1162 : }
1163 : }
1164 : return pObj;
1165 0 : }
1166 :
1167 : const TObject* AliHLTComponent::GetFirstInputObject(const char* dtID,
1168 : const char* dtOrigin,
1169 : const char* classname,
1170 : int bForce)
1171 : {
1172 : // see header file for function documentation
1173 0 : ALIHLTCOMPONENT_BASE_STOPWATCH();
1174 0 : AliHLTComponentDataType dt;
1175 0 : SetDataType(dt, dtID, dtOrigin);
1176 0 : return GetFirstInputObject(dt, classname, bForce);
1177 0 : }
1178 :
1179 : const TObject* AliHLTComponent::GetNextInputObject(int bForce)
1180 : {
1181 : // see header file for function documentation
1182 0 : ALIHLTCOMPONENT_BASE_STOPWATCH();
1183 0 : int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1, 1);
1184 : //HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(fSearchDataType).c_str());
1185 : TObject* pObj=NULL;
1186 0 : if (idx>=0) {
1187 0 : if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
1188 0 : fCurrentInputBlock=idx;
1189 0 : }
1190 : }
1191 : return pObj;
1192 0 : }
1193 :
1194 : int AliHLTComponent::FindInputBlock(const AliHLTComponentDataType& dt, int startIdx, int bObject) const
1195 : {
1196 : // see header file for function documentation
1197 : int iResult=-ENOENT;
1198 0 : if (fpInputBlocks!=NULL) {
1199 0 : int idx=startIdx<0?0:startIdx;
1200 0 : for ( ; (UInt_t)idx<fCurrentEventData.fBlockCnt && iResult==-ENOENT; idx++) {
1201 0 : if (dt!=fpInputBlocks[idx].fDataType) continue;
1202 :
1203 0 : if (bObject!=0) {
1204 0 : if (fpInputBlocks[idx].fPtr==NULL) continue;
1205 0 : AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
1206 0 : if (firstWord!=fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) continue;
1207 0 : }
1208 : iResult=idx;
1209 0 : }
1210 0 : }
1211 0 : return iResult;
1212 : }
1213 :
1214 : TObject* AliHLTComponent::CreateInputObject(int idx, int bForce)
1215 : {
1216 : // see header file for function documentation
1217 : TObject* pObj=NULL;
1218 0 : if (fpInputBlocks!=NULL) {
1219 0 : if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
1220 0 : if (fpInputBlocks[idx].fPtr) {
1221 0 : AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
1222 0 : if (firstWord==fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) {
1223 : HLTDebug("create object from block %d size %d", idx, fpInputBlocks[idx].fSize);
1224 0 : AliHLTMessage msg(fpInputBlocks[idx].fPtr, fpInputBlocks[idx].fSize);
1225 0 : TClass* objclass=msg.GetClass();
1226 0 : pObj=msg.ReadObject(objclass);
1227 0 : if (pObj && objclass) {
1228 : HLTDebug("object %p type %s created", pObj, objclass->GetName());
1229 : } else {
1230 : }
1231 : //} else {
1232 0 : } else if (bForce!=0) {
1233 0 : HLTError("size mismatch: block size %d, indicated %d", fpInputBlocks[idx].fSize, firstWord+sizeof(AliHLTUInt32_t));
1234 : }
1235 0 : } else {
1236 0 : HLTFatal("block descriptor empty");
1237 : }
1238 : } else {
1239 0 : HLTError("index %d out of range %d", idx, fCurrentEventData.fBlockCnt);
1240 : }
1241 : } else {
1242 0 : HLTError("no input blocks available");
1243 : }
1244 :
1245 0 : return pObj;
1246 0 : }
1247 :
1248 : const TObject* AliHLTComponent::GetInputObjectFromIndex(const int idx, const char* classname, int bforce)
1249 : {
1250 0 : return GetInputObject(idx, classname, bforce);
1251 : }
1252 :
1253 : TObject* AliHLTComponent::GetInputObject(int idx, const char* /*classname*/, int bForce)
1254 : {
1255 : // see header file for function documentation
1256 0 : if (fpInputObjects==NULL) {
1257 0 : fpInputObjects=new TObjArray(fCurrentEventData.fBlockCnt);
1258 0 : }
1259 : TObject* pObj=NULL;
1260 0 : if (fpInputObjects) {
1261 0 : pObj=fpInputObjects->At(idx);
1262 0 : if (pObj==NULL) {
1263 0 : pObj=CreateInputObject(idx, bForce);
1264 0 : if (pObj) {
1265 0 : fpInputObjects->AddAt(pObj, idx);
1266 0 : }
1267 : }
1268 : } else {
1269 0 : HLTFatal("memory allocation failed: TObjArray of size %d", fCurrentEventData.fBlockCnt);
1270 : }
1271 0 : return pObj;
1272 0 : }
1273 :
1274 : int AliHLTComponent::CleanupInputObjects()
1275 : {
1276 : // see header file for function documentation
1277 1035 : if (!fpInputObjects) return 0;
1278 : TObjArray* array=fpInputObjects;
1279 0 : fpInputObjects=NULL;
1280 0 : for (int i=0; i<array->GetEntriesFast(); i++) {
1281 0 : TObject* pObj=array->At(i);
1282 : // grrr, garbage collection strikes back: When read via AliHLTMessage
1283 : // (CreateInputObject), and written to a TFile afterwards, the
1284 : // TFile::Close calls ROOOT's garbage collection. No clue why the
1285 : // object ended up in the key list and needs to be deleted
1286 : //
1287 : // Matthias 09.11.2008 follow up
1288 : // This approach doesn't actually work in all cases: the object table
1289 : // can be switched off globally, the flag needs to be checked here as
1290 : // well in order to avoid memory leaks.
1291 : // This means we have to find another solution for the problem if it
1292 : // pops up again.
1293 0 : if (pObj &&
1294 0 : (!TObject::GetObjectStat() || gObjectTable->PtrIsValid(pObj))) {
1295 0 : delete pObj;
1296 : }
1297 : }
1298 0 : delete array;
1299 : return 0;
1300 345 : }
1301 :
1302 : TObject* AliHLTComponent::RemoveInputObjectFromCleanupList(const TObject* obj)
1303 : {
1304 0 : if (!fpInputObjects) return(NULL);
1305 : TObjArray* array=fpInputObjects;
1306 0 : for (int i=0; i<array->GetEntriesFast(); i++) {
1307 0 : if (array->At(i) == obj) {
1308 0 : TObject* retVal = array->At(i);
1309 0 : array->RemoveAt(i);
1310 : return(retVal);
1311 : }
1312 : }
1313 0 : return(NULL);
1314 0 : }
1315 :
1316 : AliHLTComponentDataType AliHLTComponent::GetDataType(const TObject* pObject)
1317 : {
1318 : // see header file for function documentation
1319 0 : ALIHLTCOMPONENT_BASE_STOPWATCH();
1320 : AliHLTComponentDataType dt=kAliHLTVoidDataType;
1321 0 : int idx=fCurrentInputBlock;
1322 0 : if (pObject) {
1323 0 : if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
1324 : } else {
1325 0 : HLTError("unknown object %p", pObject);
1326 : }
1327 : }
1328 0 : if (idx>=0) {
1329 0 : if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
1330 0 : dt=fpInputBlocks[idx].fDataType;
1331 0 : } else {
1332 0 : HLTFatal("severe internal error, index out of range");
1333 : }
1334 : }
1335 : return dt;
1336 0 : }
1337 :
1338 : int AliHLTComponent::GetCurrentInputBlockIndex()
1339 : {
1340 0 : return(fCurrentInputBlock);
1341 : }
1342 :
1343 : AliHLTUInt32_t AliHLTComponent::GetSpecification(const TObject* pObject)
1344 : {
1345 : // see header file for function documentation
1346 0 : ALIHLTCOMPONENT_BASE_STOPWATCH();
1347 : AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
1348 0 : int idx=fCurrentInputBlock;
1349 0 : if (pObject) {
1350 0 : if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
1351 : } else {
1352 0 : HLTError("unknown object %p", pObject);
1353 : }
1354 : }
1355 0 : if (idx>=0) {
1356 0 : if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
1357 0 : iSpec=fpInputBlocks[idx].fSpecification;
1358 0 : } else {
1359 0 : HLTFatal("severe internal error, index out of range");
1360 : }
1361 : }
1362 : return iSpec;
1363 0 : }
1364 :
1365 : int AliHLTComponent::Forward(const TObject* pObject)
1366 : {
1367 : // see header file for function documentation
1368 : int iResult=0;
1369 0 : int idx=fCurrentInputBlock;
1370 0 : if (pObject) {
1371 0 : if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
1372 : } else {
1373 0 : HLTError("unknown object %p", pObject);
1374 : iResult=-ENOENT;
1375 : }
1376 : }
1377 0 : if (idx>=0) {
1378 0 : fOutputBlocks.push_back(fpInputBlocks[idx]);
1379 0 : }
1380 0 : return iResult;
1381 : }
1382 :
1383 : int AliHLTComponent::Forward(const AliHLTComponentBlockData* pBlock)
1384 : {
1385 : // see header file for function documentation
1386 : int iResult=0;
1387 0 : int idx=fCurrentInputBlock;
1388 0 : if (pBlock) {
1389 0 : if ((idx=FindInputBlock(pBlock))>=0) {
1390 : } else {
1391 0 : HLTError("unknown Block %p", pBlock);
1392 : iResult=-ENOENT;
1393 : }
1394 : }
1395 0 : if (idx>=0) {
1396 : // check for fpInputBlocks pointer done in FindInputBlock
1397 0 : fOutputBlocks.push_back(fpInputBlocks[idx]);
1398 0 : }
1399 0 : return iResult;
1400 : }
1401 :
1402 : const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const AliHLTComponentDataType& dt)
1403 : {
1404 : // see header file for function documentation
1405 0 : ALIHLTCOMPONENT_BASE_STOPWATCH();
1406 0 : fSearchDataType=dt;
1407 0 : fClassName.clear();
1408 0 : int idx=FindInputBlock(fSearchDataType, 0);
1409 : const AliHLTComponentBlockData* pBlock=NULL;
1410 0 : if (idx>=0) {
1411 : // check for fpInputBlocks pointer done in FindInputBlock
1412 0 : pBlock=&fpInputBlocks[idx];
1413 0 : fCurrentInputBlock=idx;
1414 0 : }
1415 : return pBlock;
1416 0 : }
1417 :
1418 : const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const char* dtID,
1419 : const char* dtOrigin)
1420 : {
1421 : // see header file for function documentation
1422 0 : ALIHLTCOMPONENT_BASE_STOPWATCH();
1423 0 : AliHLTComponentDataType dt;
1424 0 : SetDataType(dt, dtID, dtOrigin);
1425 0 : return GetFirstInputBlock(dt);
1426 0 : }
1427 :
1428 : const AliHLTComponentBlockData* AliHLTComponent::GetInputBlock(int index) const
1429 : {
1430 : // see header file for function documentation
1431 0 : ALIHLTCOMPONENT_BASE_STOPWATCH();
1432 0 : assert( 0 <= index and index < (int)fCurrentEventData.fBlockCnt );
1433 0 : return &fpInputBlocks[index];
1434 0 : }
1435 :
1436 : const AliHLTComponentBlockData* AliHLTComponent::GetNextInputBlock()
1437 : {
1438 : // see header file for function documentation
1439 0 : ALIHLTCOMPONENT_BASE_STOPWATCH();
1440 0 : int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1);
1441 : const AliHLTComponentBlockData* pBlock=NULL;
1442 0 : if (idx>=0) {
1443 : // check for fpInputBlocks pointer done in FindInputBlock
1444 0 : pBlock=&fpInputBlocks[idx];
1445 0 : fCurrentInputBlock=idx;
1446 0 : }
1447 : return pBlock;
1448 0 : }
1449 :
1450 : int AliHLTComponent::FindInputBlock(const AliHLTComponentBlockData* pBlock) const
1451 : {
1452 : // see header file for function documentation
1453 : int iResult=-ENOENT;
1454 0 : if (fpInputBlocks!=NULL) {
1455 0 : if (pBlock) {
1456 0 : if (pBlock>=fpInputBlocks && pBlock<fpInputBlocks+fCurrentEventData.fBlockCnt) {
1457 0 : iResult=(int)(pBlock-fpInputBlocks);
1458 0 : }
1459 : } else {
1460 : iResult=-EINVAL;
1461 : }
1462 : }
1463 0 : return iResult;
1464 : }
1465 :
1466 : AliHLTUInt32_t AliHLTComponent::GetSpecification(const AliHLTComponentBlockData* pBlock)
1467 : {
1468 : // see header file for function documentation
1469 0 : ALIHLTCOMPONENT_BASE_STOPWATCH();
1470 : AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
1471 0 : int idx=fCurrentInputBlock;
1472 0 : if (pBlock) {
1473 0 : if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
1474 : } else {
1475 0 : HLTError("unknown Block %p", pBlock);
1476 : }
1477 : }
1478 0 : if (idx>=0) {
1479 : // check for fpInputBlocks pointer done in FindInputBlock
1480 0 : iSpec=fpInputBlocks[idx].fSpecification;
1481 0 : }
1482 : return iSpec;
1483 0 : }
1484 :
1485 : bool AliHLTComponent::CheckPushbackPeriod()
1486 : {
1487 0 : if (fPushbackPeriod>0) {
1488 : // suppress the output
1489 0 : TTimeStamp time;
1490 0 : if (fLastPushBackTime<0 || (int)time.GetSec()-fLastPushBackTime<fPushbackPeriod) return false;
1491 0 : }
1492 0 : return(true);
1493 0 : }
1494 :
1495 : int AliHLTComponent::SerializeObject(TObject* pObject, void* &buffer_tmp, size_t &size)
1496 : {
1497 : //Copy from the PushBack function below to serialize into a new buffer
1498 : //See header file for input parameter description!!!
1499 : char* &buffer = (char*&) buffer_tmp;
1500 0 : AliHLTMessage msg(kMESS_OBJECT);
1501 0 : msg.SetCompressionLevel(fCompressionLevel);
1502 0 : msg.WriteObject(pObject);
1503 0 : size_t bufsize = size;
1504 0 : size = msg.Length();
1505 0 : if (size == 0)
1506 : {
1507 0 : buffer = NULL;
1508 0 : size = 0;
1509 0 : return 0;
1510 : }
1511 0 : msg.SetLength();
1512 0 : msg.Compress();
1513 0 : char *mbuf = msg.Buffer();
1514 0 : if (msg.CompBuffer())
1515 : {
1516 0 : msg.SetLength();
1517 0 : mbuf = msg.CompBuffer();
1518 0 : size = msg.CompLength();
1519 0 : }
1520 0 : if (buffer != NULL)
1521 : {
1522 0 : if (bufsize < size) return(1);
1523 : bufsize = 0;
1524 0 : }
1525 0 : else if (buffer == NULL)
1526 : {
1527 0 : buffer = (char*) malloc(size + bufsize);
1528 0 : if (buffer == NULL) return(1);
1529 : }
1530 0 : memcpy(buffer + bufsize, mbuf, size);
1531 0 : return 0;
1532 0 : }
1533 :
1534 : int AliHLTComponent::PushBack(const TObject* pObject, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1535 : void* pHeader, int headerSize)
1536 : {
1537 : // see header file for function documentation
1538 0 : ALIHLTCOMPONENT_BASE_STOPWATCH();
1539 0 : if (!CheckPushbackPeriod()) return 0;
1540 : int iResult=0;
1541 0 : fLastObjectSize=0;
1542 0 : if (pObject) {
1543 0 : AliHLTMessage msg(kMESS_OBJECT);
1544 0 : msg.EnableSchemaEvolution(fUseSchema);
1545 0 : msg.SetCompressionLevel(fCompressionLevel);
1546 0 : msg.WriteObject(pObject);
1547 :
1548 : //chache the streamer infos during the first few times
1549 : //no need to do this every time as we mostly push the same objects
1550 0 : if (fUseSchema) {
1551 0 : const TObjArray* schemaList = msg.GetStreamerInfos();
1552 0 : if (schemaList) UpdateSchema(schemaList);
1553 0 : }
1554 :
1555 0 : Int_t iMsgLength=msg.Length();
1556 0 : if (iMsgLength>0) {
1557 : // Matthias Sep 2008
1558 : // NOTE: AliHLTMessage does implement it's own SetLength method
1559 : // which is not architecture independent. The original SetLength
1560 : // stores the size always in network byte order.
1561 : // I'm trying to remember the rational for that, might be that
1562 : // it was just some lack of knowledge. Want to change this, but
1563 : // has to be done carefullt to be backward compatible.
1564 0 : msg.SetLength(); // sets the length to the first (reserved) word
1565 :
1566 : // does nothing if the level is 0
1567 0 : msg.Compress();
1568 :
1569 0 : char *mbuf = msg.Buffer();
1570 0 : if (msg.CompBuffer()) {
1571 0 : msg.SetLength(); // set once more to have to byte order
1572 0 : mbuf = msg.CompBuffer();
1573 0 : iMsgLength = msg.CompLength();
1574 0 : }
1575 0 : assert(mbuf!=NULL);
1576 0 : iResult=InsertOutputBlock(mbuf, iMsgLength, dt, spec, pHeader, headerSize);
1577 : if (iResult>=0) {
1578 : HLTDebug("object %s (%p) size %d compression %d inserted to output", pObject->ClassName(), pObject, iMsgLength, msg.GetCompressionLevel());
1579 : }
1580 0 : fLastObjectSize=iMsgLength;
1581 0 : } else {
1582 0 : HLTError("object serialization failed for object %p", pObject);
1583 : iResult=-ENOMSG;
1584 : }
1585 0 : } else {
1586 : iResult=-EINVAL;
1587 : }
1588 : return iResult;
1589 0 : }
1590 :
1591 : int AliHLTComponent::PushBack(const TObject* pObject, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
1592 : void* pHeader, int headerSize)
1593 : {
1594 : // see header file for function documentation
1595 0 : ALIHLTCOMPONENT_BASE_STOPWATCH();
1596 0 : AliHLTComponentDataType dt;
1597 0 : SetDataType(dt, dtID, dtOrigin);
1598 0 : return PushBack(pObject, dt, spec, pHeader, headerSize);
1599 0 : }
1600 :
1601 : int AliHLTComponent::PushBack(const void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1602 : const void* pHeader, int headerSize)
1603 : {
1604 : // see header file for function documentation
1605 0 : ALIHLTCOMPONENT_BASE_STOPWATCH();
1606 0 : if (!CheckPushbackPeriod()) return(0);
1607 0 : return InsertOutputBlock(pBuffer, iSize, dt, spec, pHeader, headerSize);
1608 0 : }
1609 :
1610 : int AliHLTComponent::PushBack(const void* pBuffer, int iSize, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
1611 : const void* pHeader, int headerSize)
1612 : {
1613 : // see header file for function documentation
1614 0 : ALIHLTCOMPONENT_BASE_STOPWATCH();
1615 0 : AliHLTComponentDataType dt;
1616 0 : SetDataType(dt, dtID, dtOrigin);
1617 0 : return PushBack(pBuffer, iSize, dt, spec, pHeader, headerSize);
1618 0 : }
1619 :
1620 : int AliHLTComponent::PushBack(const std::string& pString, const AliHLTComponentDataType& dt,
1621 : AliHLTUInt32_t spec, void* pHeader, int headerSize)
1622 : {
1623 : int rc = 0;
1624 0 : rc = InsertOutputBlock(pString.c_str(), pString.size(), dt, spec, pHeader, headerSize);
1625 0 : return rc;
1626 : }
1627 :
1628 : int AliHLTComponent::InsertOutputBlock(const void* pBuffer, int iBufferSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1629 : const void* pHeader, int iHeaderSize)
1630 : {
1631 : // see header file for function documentation
1632 : int iResult=iBufferSize;
1633 0 : int iBlkSize = iBufferSize + iHeaderSize;
1634 :
1635 0 : if ((pBuffer!=NULL && iBufferSize>0) || (pHeader!=NULL && iHeaderSize>0)) {
1636 0 : if (fpOutputBuffer && iBlkSize<=(int)(fOutputBufferSize-fOutputBufferFilled)) {
1637 0 : AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
1638 :
1639 : // copy header if provided but skip if the header is the target location
1640 : // in that case it has already been copied
1641 0 : if (pHeader!=NULL && pHeader!=pTgt) {
1642 0 : memcpy(pTgt, pHeader, iHeaderSize);
1643 0 : }
1644 :
1645 0 : pTgt += (AliHLTUInt8_t) iHeaderSize;
1646 :
1647 : // copy buffer if provided but skip if buffer is the target location
1648 : // in that case it has already been copied
1649 0 : if (pBuffer!=NULL && pBuffer!=pTgt) {
1650 0 : memcpy(pTgt, pBuffer, iBufferSize);
1651 :
1652 : //AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer);
1653 : //HLTDebug("copy %d bytes from %p to output buffer %p, first word %#x", iBufferSize, pBuffer, pTgt, firstWord);
1654 0 : }
1655 : //HLTDebug("buffer inserted to output: size %d data type %s spec %#x", iBlkSize, DataType2Text(dt).c_str(), spec);
1656 0 : } else {
1657 0 : if (fpOutputBuffer) {
1658 0 : HLTError("too little space in output buffer: %d of %d, required %d", fOutputBufferSize-fOutputBufferFilled, fOutputBufferSize, iBlkSize);
1659 : } else {
1660 0 : HLTError("output buffer not available");
1661 : }
1662 : iResult=-ENOSPC;
1663 : }
1664 : }
1665 0 : if (iResult>=0) {
1666 0 : AliHLTComponentBlockData bd;
1667 0 : FillBlockData( bd );
1668 0 : bd.fOffset = fOutputBufferFilled;
1669 0 : bd.fSize = iBlkSize;
1670 0 : bd.fDataType = dt;
1671 0 : bd.fSpecification = spec;
1672 0 : fOutputBlocks.push_back( bd );
1673 0 : fOutputBufferFilled+=bd.fSize;
1674 0 : }
1675 :
1676 0 : return iResult;
1677 : }
1678 :
1679 : int AliHLTComponent::EstimateObjectSize(const TObject* pObject) const
1680 : {
1681 : // see header file for function documentation
1682 0 : if (!pObject) return 0;
1683 :
1684 0 : AliHLTMessage msg(kMESS_OBJECT);
1685 0 : msg.WriteObject(pObject);
1686 0 : return msg.Length();
1687 0 : }
1688 :
1689 : AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity, const char* dtID,
1690 : const char* dtOrigin,
1691 : AliHLTUInt32_t spec)
1692 : {
1693 : // see header file for function documentation
1694 0 : ALIHLTCOMPONENT_BASE_STOPWATCH();
1695 0 : AliHLTComponentDataType dt;
1696 0 : SetDataType(dt, dtID, dtOrigin);
1697 0 : return CreateMemoryFile(capacity, dt, spec);
1698 0 : }
1699 :
1700 : AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity,
1701 : const AliHLTComponentDataType& dt,
1702 : AliHLTUInt32_t spec)
1703 : {
1704 : // see header file for function documentation
1705 0 : ALIHLTCOMPONENT_BASE_STOPWATCH();
1706 : AliHLTMemoryFile* pFile=NULL;
1707 0 : if (capacity>=0 && static_cast<unsigned int>(capacity)<=fOutputBufferSize-fOutputBufferFilled){
1708 0 : AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
1709 0 : pFile=new AliHLTMemoryFile((char*)pTgt, capacity);
1710 0 : if (pFile) {
1711 0 : unsigned int nofBlocks=fOutputBlocks.size();
1712 0 : if (nofBlocks+1>fMemFiles.size()) {
1713 0 : fMemFiles.resize(nofBlocks+1, NULL);
1714 : }
1715 0 : if (nofBlocks<fMemFiles.size()) {
1716 0 : fMemFiles[nofBlocks]=pFile;
1717 0 : AliHLTComponentBlockData bd;
1718 0 : FillBlockData( bd );
1719 0 : bd.fOffset = fOutputBufferFilled;
1720 0 : bd.fSize = capacity;
1721 0 : bd.fDataType = dt;
1722 0 : bd.fSpecification = spec;
1723 0 : fOutputBufferFilled+=bd.fSize;
1724 0 : fOutputBlocks.push_back( bd );
1725 0 : } else {
1726 0 : HLTError("can not allocate/grow object array");
1727 0 : pFile->CloseMemoryFile(0);
1728 0 : delete pFile;
1729 : pFile=NULL;
1730 : }
1731 0 : }
1732 0 : } else {
1733 0 : HLTError("can not create memory file of size %d (%d available)", capacity, fOutputBufferSize-fOutputBufferFilled);
1734 : }
1735 : return pFile;
1736 0 : }
1737 :
1738 : AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const char* dtID,
1739 : const char* dtOrigin,
1740 : AliHLTUInt32_t spec,
1741 : float capacity)
1742 : {
1743 : // see header file for function documentation
1744 0 : ALIHLTCOMPONENT_BASE_STOPWATCH();
1745 0 : AliHLTComponentDataType dt;
1746 0 : SetDataType(dt, dtID, dtOrigin);
1747 0 : int size=fOutputBufferSize-fOutputBufferFilled;
1748 0 : if (capacity<0 || capacity>1.0) {
1749 0 : HLTError("invalid parameter: capacity %f", capacity);
1750 0 : return NULL;
1751 : }
1752 0 : size=(int)(size*capacity);
1753 0 : return CreateMemoryFile(size, dt, spec);
1754 0 : }
1755 :
1756 : AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const AliHLTComponentDataType& dt,
1757 : AliHLTUInt32_t spec,
1758 : float capacity)
1759 : {
1760 : // see header file for function documentation
1761 0 : ALIHLTCOMPONENT_BASE_STOPWATCH();
1762 0 : int size=fOutputBufferSize-fOutputBufferFilled;
1763 0 : if (capacity<0 || capacity>1.0) {
1764 0 : HLTError("invalid parameter: capacity %f", capacity);
1765 0 : return NULL;
1766 : }
1767 0 : size=(int)(size*capacity);
1768 0 : return CreateMemoryFile(size, dt, spec);
1769 0 : }
1770 :
1771 : int AliHLTComponent::Write(AliHLTMemoryFile* pFile, const TObject* pObject,
1772 : const char* key, int option)
1773 : {
1774 : // see header file for function documentation
1775 : int iResult=0;
1776 0 : if (pFile && pObject) {
1777 0 : pFile->cd();
1778 0 : iResult=pObject->Write(key, option);
1779 0 : if (iResult>0) {
1780 : // success
1781 : } else {
1782 0 : iResult=-pFile->GetErrno();
1783 0 : if (iResult==-ENOSPC) {
1784 0 : HLTError("error writing memory file, buffer too small");
1785 : }
1786 : }
1787 : } else {
1788 : iResult=-EINVAL;
1789 : }
1790 0 : return iResult;
1791 : }
1792 :
1793 : int AliHLTComponent::CloseMemoryFile(AliHLTMemoryFile* pFile)
1794 : {
1795 : // see header file for function documentation
1796 : int iResult=0;
1797 0 : if (pFile) {
1798 0 : AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
1799 : int i=0;
1800 0 : while (element!=fMemFiles.end() && iResult>=0) {
1801 0 : if (*element && *element==pFile) {
1802 0 : iResult=pFile->CloseMemoryFile();
1803 :
1804 : // sync memory files and descriptors
1805 0 : if (iResult>=0) {
1806 0 : fOutputBlocks[i].fSize=(*element)->GetSize()+(*element)->GetHeaderSize();
1807 0 : }
1808 0 : delete *element;
1809 0 : *element=NULL;
1810 0 : return iResult;
1811 : }
1812 0 : element++; i++;
1813 : }
1814 0 : HLTError("can not find memory file %p", pFile);
1815 : iResult=-ENOENT;
1816 0 : } else {
1817 : iResult=-EINVAL;
1818 : }
1819 0 : return iResult;
1820 0 : }
1821 :
1822 : int AliHLTComponent::CreateEventDoneData(AliHLTComponentEventDoneData edd)
1823 : {
1824 : // see header file for function documentation
1825 : int iResult=0;
1826 :
1827 : AliHLTComponentEventDoneData* newEDD = NULL;
1828 :
1829 0 : unsigned long newSize=edd.fDataSize;
1830 0 : if (fEventDoneData)
1831 0 : newSize += fEventDoneData->fDataSize;
1832 :
1833 0 : if (newSize>fEventDoneDataSize) {
1834 0 : newEDD = reinterpret_cast<AliHLTComponentEventDoneData*>( new AliHLTUInt8_t[ sizeof(AliHLTComponentEventDoneData)+newSize ] );
1835 0 : if (!newEDD)
1836 0 : return -ENOMEM;
1837 0 : newEDD->fStructSize = sizeof(AliHLTComponentEventDoneData);
1838 0 : newEDD->fDataSize = newSize;
1839 0 : newEDD->fData = reinterpret_cast<AliHLTUInt8_t*>(newEDD)+newEDD->fStructSize;
1840 : unsigned long long offset = 0;
1841 0 : if (fEventDoneData) {
1842 0 : memcpy( newEDD->fData, fEventDoneData->fData, fEventDoneData->fDataSize );
1843 0 : offset += fEventDoneData->fDataSize;
1844 0 : }
1845 0 : memcpy( reinterpret_cast<AliHLTUInt8_t*>(newEDD->fData)+offset, edd.fData, edd.fDataSize );
1846 0 : if (fEventDoneData)
1847 0 : delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
1848 0 : fEventDoneData = newEDD;
1849 0 : fEventDoneDataSize = newSize;
1850 0 : }
1851 0 : else if (fEventDoneData) {
1852 0 : memcpy( reinterpret_cast<AliHLTUInt8_t*>(fEventDoneData->fData)+fEventDoneData->fDataSize, edd.fData, edd.fDataSize );
1853 0 : fEventDoneData->fDataSize += edd.fDataSize;
1854 0 : }
1855 : else {
1856 0 : HLTError("internal mismatch, fEventDoneData=%d but buffer is NULL", fEventDoneDataSize);
1857 : iResult=-EFAULT;
1858 : }
1859 0 : return iResult;
1860 0 : }
1861 :
1862 : namespace
1863 : {
1864 : // helper function for std:sort, implements an operator<
1865 : bool SortComponentStatisticsById(const AliHLTComponentStatistics& a, const AliHLTComponentStatistics& b)
1866 : {
1867 : return a.fId<b.fId;
1868 : }
1869 :
1870 : // helper function for std:sort
1871 : bool SortComponentStatisticsDescendingByLevel(const AliHLTComponentStatistics& a, const AliHLTComponentStatistics& b)
1872 : {
1873 : return a.fId>b.fId;
1874 : }
1875 :
1876 : // helper class to define operator== between AliHLTComponentStatistics and AliHLTComponentStatistics.fId
1877 : class AliHLTComponentStatisticsId {
1878 : public:
1879 0 : AliHLTComponentStatisticsId(AliHLTUInt32_t id) : fId(id) {}
1880 : AliHLTComponentStatisticsId(const AliHLTComponentStatisticsId& src) : fId(src.fId) {}
1881 : AliHLTComponentStatisticsId& operator=(const AliHLTComponentStatisticsId& src) {
1882 : if (this==&src) return *this;
1883 : fId=src.fId; return *this;
1884 : }
1885 0 : bool operator==(const AliHLTComponentStatistics& a) const {return a.fId==fId;}
1886 : private:
1887 : AliHLTComponentStatisticsId();
1888 : AliHLTUInt32_t fId;
1889 : };
1890 :
1891 : // operator for std::find of AliHLTComponentStatistics by id
1892 : bool operator==(const AliHLTComponentStatistics& a, const AliHLTComponentStatisticsId& b)
1893 : {
1894 0 : return b==a;
1895 : }
1896 :
1897 : bool AliHLTComponentStatisticsCompareIds(const AliHLTComponentStatistics& a, const AliHLTComponentStatistics& b)
1898 : {
1899 : return a.fId==b.fId;
1900 : }
1901 :
1902 : // helper class to define operator== between AliHLTComponentBlockData and AliHLTComponentBlockData.fSpecification
1903 : class AliHLTComponentBlockDataSpecification {
1904 : public:
1905 0 : AliHLTComponentBlockDataSpecification(AliHLTUInt32_t specification) : fSpecification(specification) {}
1906 : AliHLTComponentBlockDataSpecification(const AliHLTComponentBlockDataSpecification& src) : fSpecification(src.fSpecification) {}
1907 : AliHLTComponentBlockDataSpecification& operator=(const AliHLTComponentBlockDataSpecification& src) {
1908 : if (this==&src) return *this;
1909 : fSpecification=src.fSpecification; return *this;
1910 : }
1911 0 : bool operator==(const AliHLTComponentBlockData& bd) const {return bd.fSpecification==fSpecification;}
1912 : private:
1913 : AliHLTComponentBlockDataSpecification();
1914 : AliHLTUInt32_t fSpecification;
1915 : };
1916 :
1917 : // operator for std::find of AliHLTComponentBlockData by specification
1918 : bool operator==(const AliHLTComponentBlockData& bd, const AliHLTComponentBlockDataSpecification& spec)
1919 : {
1920 0 : return spec==bd;
1921 : }
1922 :
1923 : // operator for std::find
1924 : bool operator==(const AliHLTComponentBlockData& a, const AliHLTComponentBlockData& b)
1925 : {
1926 : if (!MatchExactly(a.fDataType,b.fDataType)) return false;
1927 : return a.fSpecification==b.fSpecification;
1928 : }
1929 :
1930 : } // end of namespace
1931 :
1932 : int AliHLTComponent::ProcessEvent( const AliHLTComponentEventData& evtData,
1933 : const AliHLTComponentBlockData* blocks,
1934 : AliHLTComponentTriggerData& trigData,
1935 : AliHLTUInt8_t* outputPtr,
1936 : AliHLTUInt32_t& size,
1937 : AliHLTUInt32_t& outputBlockCnt,
1938 : AliHLTComponentBlockData*& outputBlocks,
1939 : AliHLTComponentEventDoneData*& edd )
1940 : {
1941 : // see header file for function documentation
1942 0 : HLTLogKeyword(fChainId.c_str());
1943 0 : ALIHLTCOMPONENT_BASE_STOPWATCH();
1944 : int iResult=0;
1945 0 : fCurrentEvent=evtData.fEventID;
1946 0 : fCurrentEventData=evtData;
1947 0 : fpInputBlocks=blocks;
1948 0 : fCurrentInputBlock=-1;
1949 0 : fSearchDataType=kAliHLTAnyDataType;
1950 0 : fpOutputBuffer=outputPtr;
1951 0 : fOutputBufferSize=size;
1952 0 : fOutputBufferFilled=0;
1953 0 : fOutputBlocks.clear();
1954 0 : outputBlockCnt=0;
1955 0 : outputBlocks=NULL;
1956 :
1957 0 : AliHLTComponentBlockDataList forwardedBlocks;
1958 :
1959 : // optional component statistics
1960 0 : AliHLTComponentStatisticsList compStats;
1961 : bool bAddComponentTableEntry=false;
1962 0 : vector<AliHLTUInt32_t> parentComponentTables;
1963 : int processingLevel=-1;
1964 : #if defined(HLT_COMPONENT_STATISTICS)
1965 : if ((fFlags&kDisableComponentStat)==0) {
1966 : AliHLTComponentStatistics outputStat;
1967 : memset(&outputStat, 0, sizeof(AliHLTComponentStatistics));
1968 : outputStat.fStructSize=sizeof(AliHLTComponentStatistics);
1969 : outputStat.fId=fChainIdCrc;
1970 : if (fpBenchmark) {
1971 : fpBenchmark->Stop();
1972 : outputStat.fComponentCycleTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
1973 : fpBenchmark->Reset();
1974 : fpBenchmark->Start();
1975 : }
1976 : compStats.push_back(outputStat);
1977 : }
1978 : #endif // HLT_COMPONENT_STATISTICS
1979 :
1980 : // data processing is skipped
1981 : // - if there are only steering events in the block list.
1982 : // For the sake of data source components data processing
1983 : // is not skipped if there is no block list at all or if it
1984 : // just contains the eventType block
1985 : // - always skipped if the event is of type
1986 : // - gkAliEventTypeConfiguration
1987 : // - gkAliEventTypeReadPreprocessor
1988 : const unsigned int skipModeDefault=0x1;
1989 : const unsigned int skipModeForce=0x2;
1990 : unsigned int bSkipDataProcessing=skipModeDefault;
1991 :
1992 : // find special events
1993 0 : if (fpInputBlocks && evtData.fBlockCnt>0) {
1994 : // first look for all special events and execute in the appropriate
1995 : // sequence afterwords
1996 : int indexComConfEvent=-1;
1997 : int indexUpdtDCSEvent=-1;
1998 : int indexSOREvent=-1;
1999 : int indexEOREvent=-1;
2000 : int indexECSParamBlock=-1;
2001 0 : for (unsigned int i=0; i<evtData.fBlockCnt && iResult>=0; i++) {
2002 0 : if (fpInputBlocks[i].fDataType==kAliHLTDataTypeSOR) {
2003 : indexSOREvent=i;
2004 : // the AliHLTCalibrationProcessor relies on the SOR and EOR events
2005 0 : bSkipDataProcessing&=~skipModeDefault;
2006 0 : } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeRunType) {
2007 : // run type string
2008 : // handling is not clear yet
2009 0 : if (fpInputBlocks[i].fPtr) {
2010 : HLTDebug("got run type \"%s\"\n", fpInputBlocks[i].fPtr);
2011 : }
2012 0 : } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEOR) {
2013 : indexEOREvent=i;
2014 : // the calibration processor relies on the SOR and EOR events
2015 0 : bSkipDataProcessing&=~skipModeDefault;
2016 0 : } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeDDL) {
2017 : // DDL list
2018 : // this event is most likely deprecated
2019 0 : } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComConf) {
2020 : indexComConfEvent=i;
2021 0 : } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeUpdtDCS) {
2022 : indexUpdtDCSEvent=i;
2023 0 : } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEvent) {
2024 0 : fEventType=fpInputBlocks[i].fSpecification;
2025 0 : if (fEventType != gkAliEventTypeConfiguration and
2026 0 : fEventType != gkAliEventTypeReadPreprocessor
2027 : )
2028 : {
2029 : // We can actually get the event type from the CDH if it is valid.
2030 : // Otherwise just use the specification of the input block.
2031 0 : AliHLTCDHWrapper cdh;
2032 0 : if (ExtractTriggerData(trigData, NULL, NULL, &cdh, NULL) == 0)
2033 : {
2034 0 : fEventType = ExtractEventTypeFromCDH(&cdh);
2035 0 : }
2036 0 : }
2037 :
2038 : // skip always in case of gkAliEventTypeConfiguration
2039 0 : if (fpInputBlocks[i].fSpecification==gkAliEventTypeConfiguration) bSkipDataProcessing|=skipModeForce;
2040 :
2041 : // skip always in case of gkAliEventTypeReadPreprocessor
2042 0 : if (fpInputBlocks[i].fSpecification==gkAliEventTypeReadPreprocessor) bSkipDataProcessing|=skipModeForce;
2043 :
2044 : // never skip if the event type block is the only block
2045 0 : if (evtData.fBlockCnt==1) bSkipDataProcessing&=~skipModeDefault;
2046 :
2047 0 : } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentStatistics) {
2048 0 : if (compStats.size()>0) {
2049 0 : AliHLTUInt8_t* pData=reinterpret_cast<AliHLTUInt8_t*>(fpInputBlocks[i].fPtr);
2050 0 : for (AliHLTUInt32_t offset=0;
2051 0 : offset+sizeof(AliHLTComponentStatistics)<=fpInputBlocks[i].fSize;
2052 0 : offset+=sizeof(AliHLTComponentStatistics)) {
2053 0 : AliHLTComponentStatistics* pStat=reinterpret_cast<AliHLTComponentStatistics*>(pData+offset);
2054 0 : if (pStat && compStats[0].fLevel<=pStat->fLevel) {
2055 0 : compStats[0].fLevel=pStat->fLevel+1;
2056 0 : }
2057 0 : if (find(compStats.begin(), compStats.end(), AliHLTComponentStatisticsId(pStat->fId))==compStats.end()) {
2058 0 : compStats.push_back(*pStat);
2059 : }
2060 : }
2061 0 : }
2062 0 : } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentTable) {
2063 0 : AliHLTComponentBlockDataList::iterator element=forwardedBlocks.begin();
2064 0 : while ((element=find(element, forwardedBlocks.end(), AliHLTComponentBlockDataSpecification(fpInputBlocks[i].fSpecification)))!=forwardedBlocks.end()) {
2065 0 : if (element->fDataType==fpInputBlocks[i].fDataType) break;
2066 : // TODO: think about some more checks inclusing also the actual data buffers
2067 : // this has to handle multiplicity>1 in the online system, where all components
2068 : // send the information on SOR, because this event is broadcasted
2069 : }
2070 0 : if (element==forwardedBlocks.end()) {
2071 0 : forwardedBlocks.push_back(fpInputBlocks[i]);
2072 : }
2073 0 : parentComponentTables.push_back(fpInputBlocks[i].fSpecification);
2074 0 : if (fpInputBlocks[i].fSize>=sizeof(AliHLTComponentTableEntry)) {
2075 0 : const AliHLTComponentTableEntry* entry=reinterpret_cast<AliHLTComponentTableEntry*>(fpInputBlocks[i].fPtr);
2076 0 : if (entry->fStructSize==sizeof(AliHLTComponentTableEntry)) {
2077 0 : if (processingLevel<0 || processingLevel<=(int)entry->fLevel)
2078 0 : processingLevel=entry->fLevel+1;
2079 : }
2080 0 : }
2081 0 : } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeECSParam) {
2082 : indexECSParamBlock=i;
2083 0 : } else {
2084 : // the processing function is called if there is at least one
2085 : // non-steering data block. Steering blocks are not filtered out
2086 : // for sake of performance
2087 0 : bSkipDataProcessing&=~skipModeDefault;
2088 0 : if (compStats.size()>0) {
2089 0 : compStats[0].fInputBlockCount++;
2090 0 : compStats[0].fTotalInputSize+=fpInputBlocks[i].fSize;
2091 0 : }
2092 : }
2093 : }
2094 :
2095 0 : if (indexSOREvent>=0) {
2096 : // start of run
2097 : bAddComponentTableEntry=true;
2098 0 : compStats.clear(); // no component statistics for SOR
2099 0 : if (fpRunDesc==NULL) {
2100 0 : fpRunDesc=new AliHLTRunDesc;
2101 0 : if (fpRunDesc) *fpRunDesc=kAliHLTVoidRunDesc;
2102 : }
2103 0 : if (fpRunDesc) {
2104 0 : AliHLTRunDesc rundesc;
2105 0 : if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexSOREvent, "AliHLTRunDesc", "SOR"))>0) {
2106 0 : if (fpRunDesc->fRunNo==kAliHLTVoidRunNo) {
2107 0 : *fpRunDesc=rundesc;
2108 : HLTDebug("set run decriptor, run no %d", fpRunDesc->fRunNo);
2109 0 : SetCDBRunNo(fpRunDesc->fRunNo);
2110 0 : } else if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
2111 0 : HLTWarning("already set run properties run no %d, ignoring SOR with run no %d", fpRunDesc->fRunNo, rundesc.fRunNo);
2112 : }
2113 : }
2114 0 : } else {
2115 : iResult=-ENOMEM;
2116 : }
2117 :
2118 0 : if (indexECSParamBlock>=0) {
2119 0 : if (fpInputBlocks[indexECSParamBlock].fSize>0) {
2120 0 : const char* param=reinterpret_cast<const char*>(fpInputBlocks[indexECSParamBlock].fPtr);
2121 0 : TString paramString;
2122 0 : if (param[fpInputBlocks[indexECSParamBlock].fSize-1]!=0) {
2123 0 : HLTWarning("ECS parameter string not terminated");
2124 0 : paramString.Insert(0, param, fpInputBlocks[indexECSParamBlock].fSize);
2125 0 : paramString+="";
2126 : } else {
2127 0 : paramString=param;
2128 : }
2129 0 : ScanECSParam(paramString.Data());
2130 0 : } else {
2131 0 : HLTWarning("empty ECS parameter received");
2132 : }
2133 : } else {
2134 : // TODO: later on we might throw a warning here since the CTP trigger classes
2135 : // should be mandatory
2136 : }
2137 : }
2138 0 : if (indexEOREvent>=0) {
2139 0 : fLastPushBackTime=0; // always send at EOR
2140 : bAddComponentTableEntry=true;
2141 0 : compStats.clear(); // no component statistics for EOR
2142 0 : if (fpRunDesc!=NULL) {
2143 0 : if (fpRunDesc) {
2144 0 : AliHLTRunDesc rundesc;
2145 0 : if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexEOREvent, "AliHLTRunDesc", "SOR"))>0) {
2146 0 : if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
2147 0 : HLTWarning("run no mismatch: SOR %d, EOR %d", fpRunDesc->fRunNo, rundesc.fRunNo);
2148 : } else {
2149 : HLTDebug("EOR run no %d", fpRunDesc->fRunNo);
2150 : }
2151 : }
2152 : // we do not unload the fpRunDesc struct here in order to have the run information
2153 : // available during the event processing
2154 : // https://savannah.cern.ch/bugs/?39711
2155 : // the info will be cleared in DeInit
2156 0 : }
2157 : } else {
2158 0 : HLTWarning("did not receive SOR, ignoring EOR");
2159 : }
2160 : }
2161 0 : if (fEventType==gkAliEventTypeConfiguration) {
2162 0 : if (indexComConfEvent>=0) {
2163 0 : TString cdbEntry;
2164 0 : if (indexComConfEvent>=0 && fpInputBlocks[indexComConfEvent].fPtr!=NULL && fpInputBlocks[indexComConfEvent].fSize>0) {
2165 0 : cdbEntry.Append(reinterpret_cast<const char*>(fpInputBlocks[indexComConfEvent].fPtr), fpInputBlocks[indexComConfEvent].fSize);
2166 : }
2167 : HLTDebug("received component configuration command: entry %s", cdbEntry.IsNull()?"none":cdbEntry.Data());
2168 0 : int tmpResult=Reconfigure(cdbEntry[0]==0?NULL:cdbEntry.Data(), fChainId.c_str());
2169 0 : if (tmpResult<0) {
2170 0 : HLTWarning("reconfiguration of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
2171 : }
2172 0 : } else {
2173 0 : ALIHLTERRORGUARD(1, "incomplete Configure event, missing parameter data block");
2174 : }
2175 : }
2176 0 : if (fEventType==gkAliEventTypeReadPreprocessor) {
2177 0 : if (indexUpdtDCSEvent>=0) {
2178 0 : TString modules;
2179 0 : if (fpInputBlocks[indexUpdtDCSEvent].fPtr!=NULL && fpInputBlocks[indexUpdtDCSEvent].fSize>0) {
2180 0 : modules.Append(reinterpret_cast<const char*>(fpInputBlocks[indexUpdtDCSEvent].fPtr), fpInputBlocks[indexUpdtDCSEvent].fSize);
2181 : }
2182 : HLTDebug("received preprocessor update command: detectors %s", modules.IsNull()?"ALL":modules.Data());
2183 0 : int tmpResult=ReadPreprocessorValues(modules[0]==0?"ALL":modules.Data());
2184 0 : if (tmpResult<0) {
2185 0 : HLTWarning("preprocessor update of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
2186 : }
2187 0 : } else {
2188 0 : ALIHLTERRORGUARD(1, "incomplete ReadPreprocessor event, missing parameter data block");
2189 : }
2190 : }
2191 0 : } else {
2192 : // processing function needs to be called if there are no input data
2193 : // blocks in order to make data source components working.
2194 : bSkipDataProcessing&=~skipModeDefault;
2195 : }
2196 :
2197 : // data processing is not skipped if the component explicitly asks
2198 : // for the private blocks
2199 0 : if ((fFlags&kRequireSteeringBlocks)!=0) bSkipDataProcessing=0;
2200 :
2201 : // data processing is not skipped for data sources
2202 0 : if (GetComponentType()==AliHLTComponent::kSource) bSkipDataProcessing=0;
2203 :
2204 0 : if (fpCTPData) {
2205 : // set the active triggers for this event
2206 0 : fpCTPData->SetTriggers(trigData);
2207 : // increment CTP trigger counters if available
2208 0 : if (IsDataEvent()) fpCTPData->Increment(trigData);
2209 : }
2210 :
2211 : // Check if the event processing should be skipped because of the
2212 : // down scaling from the event modulo argument. Using a prime number
2213 : // as pre divisor to pseudo-randomise the event number to get a more
2214 : // uniform distribution.
2215 0 : if (fEventModulo > 1)
2216 : {
2217 0 : bSkipDataProcessing |= ( ((AliHLTUInt64_t(fCurrentEvent) / AliHLTUInt64_t(4789)) % AliHLTUInt64_t(fEventModulo)) != 0 );
2218 0 : }
2219 :
2220 0 : AliHLTComponentBlockDataList blockData;
2221 0 : if (iResult>=0 && !bSkipDataProcessing)
2222 : { // dont delete, sets the scope for the stopwatch guard
2223 : // do not use ALIHLTCOMPONENT_DA_STOPWATCH(); macro
2224 : // in order to avoid 'shadowed variable' warning
2225 0 : AliHLTStopwatchGuard swguard2(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)kSWDA)):NULL);
2226 0 : AliHLTMisc::AliOnlineGuard onlineGuard;
2227 0 : iResult=DoProcessing(evtData, blocks, trigData, outputPtr, size, blockData, edd);
2228 0 : } // end of the scope of the stopwatch guard
2229 0 : if (iResult>=0 && !bSkipDataProcessing) {
2230 0 : if (fOutputBlocks.size()>0) {
2231 : // High Level interface
2232 :
2233 : //HLTDebug("got %d block(s) via high level interface", fOutputBlocks.size());
2234 : // sync memory files and descriptors
2235 0 : AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
2236 : int i=0;
2237 0 : while (element!=fMemFiles.end() && iResult>=0) {
2238 0 : if (*element) {
2239 0 : if ((*element)->IsClosed()==0) {
2240 0 : HLTWarning("memory file has not been closed, force flush");
2241 0 : iResult=CloseMemoryFile(*element);
2242 0 : }
2243 : }
2244 0 : element++; i++;
2245 : }
2246 :
2247 0 : if (iResult>=0) {
2248 : // create the descriptor list
2249 0 : if (blockData.size()>0) {
2250 0 : HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks");
2251 : iResult=-EFAULT;
2252 0 : } else {
2253 0 : if (compStats.size()>0 && IsDataEvent()) {
2254 0 : int offset=AddComponentStatistics(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, compStats);
2255 0 : if (offset>0) fOutputBufferFilled+=offset;
2256 0 : }
2257 0 : if (bAddComponentTableEntry) {
2258 0 : int offset=AddComponentTableEntry(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, parentComponentTables, processingLevel);
2259 0 : if (offset>0) size+=offset;
2260 0 : }
2261 0 : if (forwardedBlocks.size()>0) {
2262 0 : fOutputBlocks.insert(fOutputBlocks.end(), forwardedBlocks.begin(), forwardedBlocks.end());
2263 0 : }
2264 0 : iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks);
2265 0 : size=fOutputBufferFilled;
2266 : }
2267 : }
2268 0 : } else {
2269 : // Low Level interface
2270 0 : if (blockData.empty() && size!=0) {
2271 : // set the size to zero because there is no announced data
2272 : //HLTWarning("no output blocks added by component but output buffer filled %d of %d", size, fOutputBufferSize);
2273 0 : size=0;
2274 0 : }
2275 :
2276 0 : if (compStats.size()>0) {
2277 0 : int offset=AddComponentStatistics(blockData, fpOutputBuffer, fOutputBufferSize, size, compStats);
2278 0 : if (offset>0) size+=offset;
2279 0 : }
2280 0 : if (bAddComponentTableEntry) {
2281 0 : int offset=AddComponentTableEntry(blockData, fpOutputBuffer, fOutputBufferSize, size, parentComponentTables, processingLevel);
2282 0 : if (offset>0) size+=offset;
2283 0 : }
2284 0 : if (forwardedBlocks.size()>0) {
2285 0 : blockData.insert(blockData.end(), forwardedBlocks.begin(), forwardedBlocks.end());
2286 0 : }
2287 0 : iResult=MakeOutputDataBlockList(blockData, &outputBlockCnt, &outputBlocks);
2288 : }
2289 0 : if (iResult<0) {
2290 0 : HLTFatal("component %s (%p): can not convert output block descriptor list", GetComponentID(), this);
2291 : }
2292 : }
2293 0 : if (iResult<0 || bSkipDataProcessing) {
2294 0 : outputBlockCnt=0;
2295 0 : outputBlocks=NULL;
2296 0 : }
2297 0 : CleanupInputObjects();
2298 0 : if (iResult>=0 && IsDataEvent()) {
2299 0 : IncrementEventCounter();
2300 0 : }
2301 0 : if (outputBlockCnt==0) {
2302 : // no output blocks, set size to 0
2303 0 : size=0;
2304 0 : }
2305 :
2306 : // reset the internal EventData struct
2307 0 : FillEventData(fCurrentEventData);
2308 :
2309 : // reset the active triggers
2310 0 : if (fpCTPData) fpCTPData->SetTriggers(0);
2311 :
2312 : // set the time for the pushback period
2313 0 : if (fPushbackPeriod>0) {
2314 : // suppress the output
2315 0 : TTimeStamp time;
2316 0 : if (fLastPushBackTime<0) {
2317 : // choose a random offset at beginning to equalize traffic for multiple instances
2318 : // of the component
2319 : struct timespec ts;
2320 : #ifdef __MACH__ // OS X does not have clock_gettime, use clock_get_time
2321 0 : clock_serv_t cclock;
2322 0 : mach_timespec_t mts;
2323 0 : host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
2324 0 : clock_get_time(cclock, &mts);
2325 0 : mach_port_deallocate(mach_task_self(), cclock);
2326 0 : ts.tv_sec = mts.tv_sec;
2327 0 : ts.tv_nsec = mts.tv_nsec;
2328 : #else
2329 : clock_gettime(CLOCK_REALTIME, &ts);
2330 : #endif
2331 0 : gRandom->SetSeed(ts.tv_nsec);
2332 0 : fLastPushBackTime=time.GetSec();
2333 0 : fLastPushBackTime+=fPushbackPeriod/2-gRandom->Integer(fPushbackPeriod);
2334 : //HLTImportant("time: %i, fLastPushBackTime: %i",(int)time.GetSec(),fLastPushBackTime);
2335 0 : } else if ((int)time.GetSec()-fLastPushBackTime >= fPushbackPeriod) {
2336 0 : if (outputBlockCnt) fLastPushBackTime=time.GetSec() - gRandom->Integer(fPushbackPeriod/3);
2337 : }
2338 0 : }
2339 :
2340 : return iResult;
2341 0 : }
2342 :
2343 : int AliHLTComponent::AddComponentStatistics(AliHLTComponentBlockDataList& blocks,
2344 : AliHLTUInt8_t* buffer,
2345 : AliHLTUInt32_t bufferSize,
2346 : AliHLTUInt32_t offset,
2347 : AliHLTComponentStatisticsList& stats) const
2348 : {
2349 : // see header file for function documentation
2350 : int iResult=0;
2351 0 : if ((fFlags&kDisableComponentStat)!=0) return 0;
2352 : #if defined(HLT_COMPONENT_STATISTICS)
2353 : if (stats.size()==0) return -ENOENT;
2354 : // check if there is space for at least one entry
2355 : if (offset+sizeof(AliHLTComponentStatistics)>bufferSize) return 0;
2356 : stats[0].fTotalOutputSize=offset;
2357 : stats[0].fOutputBlockCount=blocks.size();
2358 : if (fpBenchmark) {
2359 : fpBenchmark->Stop();
2360 : stats[0].fTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
2361 : stats[0].fCTime=(AliHLTUInt32_t)(fpBenchmark->CpuTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
2362 : fpBenchmark->Continue();
2363 : }
2364 :
2365 : sort(stats.begin(), stats.end(), SortComponentStatisticsDescendingByLevel);
2366 :
2367 : // shrink the number of entries if the buffer is too small
2368 : if (offset+stats.size()*sizeof(AliHLTComponentStatistics)>bufferSize) {
2369 : unsigned originalSize=stats.size();
2370 : AliHLTUInt32_t removedLevel=0;
2371 : do {
2372 : // remove all entries of the level of the last entry
2373 : removedLevel=stats.back().fLevel;
2374 : AliHLTComponentStatisticsList::iterator element=stats.begin();
2375 : element++;
2376 : while (element!=stats.end()) {
2377 : if (element->fLevel<=removedLevel) {
2378 : element=stats.erase(element);
2379 : } else {
2380 : element++;
2381 : }
2382 : }
2383 : } while (stats.size()>1 &&
2384 : (offset+stats.size()*sizeof(AliHLTComponentStatistics)>bufferSize));
2385 : HLTWarning("too little space in output buffer to add block of %d statistics entries (size %d), available %d, removed %d entries",
2386 : originalSize, sizeof(AliHLTComponentStatistics), bufferSize-offset, originalSize-stats.size());
2387 : } else {
2388 : HLTDebug("adding block of %d statistics entries", stats.size());
2389 : }
2390 : assert(stats.size()>0);
2391 : if (stats.size()==0) return 0;
2392 :
2393 : if (offset+stats.size()*sizeof(AliHLTComponentStatistics)<=bufferSize) {
2394 : AliHLTComponentBlockData bd;
2395 : FillBlockData( bd );
2396 : bd.fOffset = offset;
2397 : bd.fSize = stats.size()*sizeof(AliHLTComponentStatistics);
2398 : bd.fDataType = kAliHLTDataTypeComponentStatistics;
2399 : bd.fSpecification = fChainIdCrc;
2400 : memcpy(buffer+offset, &(stats[0]), bd.fSize);
2401 : blocks.push_back(bd);
2402 : iResult=bd.fSize;
2403 : }
2404 : #else
2405 0 : if (blocks.size() && buffer && bufferSize && offset && stats.size()) {
2406 : // get rid of warning
2407 : }
2408 : #endif // HLT_COMPONENT_STATISTICS
2409 0 : return iResult;
2410 0 : }
2411 :
2412 : int AliHLTComponent::AddComponentTableEntry(AliHLTComponentBlockDataList& blocks,
2413 : AliHLTUInt8_t* buffer,
2414 : AliHLTUInt32_t bufferSize,
2415 : AliHLTUInt32_t offset,
2416 : const vector<AliHLTUInt32_t>& parents,
2417 : int processingLevel) const
2418 : {
2419 : // see header file for function documentation
2420 : int iResult=0;
2421 0 : if ((fFlags&kDisableComponentStat)!=0) return 0;
2422 : #if defined(HLT_COMPONENT_STATISTICS)
2423 : // the payload consists of the AliHLTComponentTableEntry struct,
2424 : // followed by a an array of 32bit crc chain ids and the component
2425 : // description string
2426 : unsigned int payloadSize=sizeof(AliHLTComponentTableEntry);
2427 : payloadSize+=parents.size()*sizeof(AliHLTUInt32_t);
2428 :
2429 : // the component description has the following format:
2430 : // chain-id{component-id:arguments}
2431 : const char* componentId=const_cast<AliHLTComponent*>(this)->GetComponentID();
2432 : unsigned int descriptionSize=fChainId.size()+1;
2433 : descriptionSize+=2; // the '{}' around the component id
2434 : descriptionSize+=strlen(componentId);
2435 : descriptionSize+=1; // the ':' between component id and arguments
2436 : descriptionSize+=fComponentArgs.size();
2437 :
2438 : payloadSize+=descriptionSize;
2439 : if (buffer && (offset+payloadSize<=bufferSize)) {
2440 : AliHLTUInt8_t* pTgt=buffer+offset;
2441 : memset(pTgt, 0, payloadSize);
2442 :
2443 : // write entry
2444 : AliHLTComponentTableEntry* pEntry=reinterpret_cast<AliHLTComponentTableEntry*>(pTgt);
2445 : pEntry->fStructSize=sizeof(AliHLTComponentTableEntry);
2446 : pEntry->fLevel=processingLevel>=0?processingLevel:0;
2447 : pEntry->fNofParents=parents.size();
2448 : pEntry->fSizeDescription=descriptionSize;
2449 : pTgt=pEntry->fBuffer;
2450 :
2451 : // write array of parents
2452 : if (parents.size()>0) {
2453 : unsigned int copy=parents.size()*sizeof(vector<AliHLTUInt32_t>::value_type);
2454 : memcpy(pTgt, &parents[0], parents.size()*sizeof(vector<AliHLTUInt32_t>::value_type));
2455 : pTgt+=copy;
2456 : }
2457 :
2458 : // write component description
2459 : memcpy(pTgt, fChainId.c_str(), fChainId.size());
2460 : pTgt+=fChainId.size();
2461 : *pTgt++='{';
2462 : memcpy(pTgt, componentId, strlen(componentId));
2463 : pTgt+=strlen(componentId);
2464 : *pTgt++=':';
2465 : memcpy(pTgt, fComponentArgs.c_str(), fComponentArgs.size());
2466 : pTgt+=fComponentArgs.size();
2467 : *pTgt++='}';
2468 : *pTgt++=0;
2469 :
2470 : AliHLTComponentBlockData bd;
2471 : FillBlockData( bd );
2472 : bd.fOffset = offset;
2473 : bd.fSize = payloadSize;
2474 : bd.fDataType = kAliHLTDataTypeComponentTable;
2475 : bd.fSpecification = fChainIdCrc;
2476 : blocks.push_back(bd);
2477 : iResult=bd.fSize;
2478 : }
2479 : #else
2480 0 : if (blocks.size() && buffer && bufferSize && offset && parents.size() && processingLevel) {
2481 : // get rid of warning
2482 : }
2483 : #endif // HLT_COMPONENT_STATISTICS
2484 0 : return iResult;
2485 0 : }
2486 :
2487 : AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard()
2488 : :
2489 0 : fpStopwatch(NULL),
2490 0 : fpPrec(NULL)
2491 0 : {
2492 : // standard constructor (not for use)
2493 0 : }
2494 :
2495 : AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(TStopwatch* pStopwatch)
2496 : :
2497 0 : fpStopwatch(pStopwatch),
2498 0 : fpPrec(NULL)
2499 0 : {
2500 : // constructor
2501 :
2502 : // check for already existing guard
2503 0 : if (fgpCurrent) fpPrec=fgpCurrent;
2504 0 : fgpCurrent=this;
2505 :
2506 : // stop the preceeding guard if it controls a different stopwatch
2507 : int bStart=1;
2508 0 : if (fpPrec && fpPrec!=this) bStart=fpPrec->Hold(fpStopwatch);
2509 :
2510 : // start the stopwatch if the current guard controls a different one
2511 0 : if (fpStopwatch && bStart==1) fpStopwatch->Start(kFALSE);
2512 0 : }
2513 :
2514 : AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(const AliHLTStopwatchGuard&)
2515 : :
2516 0 : fpStopwatch(NULL),
2517 0 : fpPrec(NULL)
2518 0 : {
2519 : //
2520 : // copy constructor not for use
2521 : //
2522 0 : }
2523 :
2524 : AliHLTComponent::AliHLTStopwatchGuard& AliHLTComponent::AliHLTStopwatchGuard::operator=(const AliHLTStopwatchGuard& other)
2525 : {
2526 : //
2527 : // assignment operator not for use
2528 : //
2529 0 : if (this==&other) return *this;
2530 0 : fpStopwatch=NULL;
2531 0 : fpPrec=NULL;
2532 0 : return *this;
2533 0 : }
2534 :
2535 : AliHLTComponent::AliHLTStopwatchGuard* AliHLTComponent::AliHLTStopwatchGuard::fgpCurrent=NULL;
2536 :
2537 : AliHLTComponent::AliHLTStopwatchGuard::~AliHLTStopwatchGuard()
2538 0 : {
2539 : // destructor
2540 :
2541 : // resume the preceeding guard if it controls a different stopwatch
2542 : int bStop=1;
2543 0 : if (fpPrec && fpPrec!=this) bStop=fpPrec->Resume(fpStopwatch);
2544 :
2545 : // stop the stopwatch if the current guard controls a different one
2546 0 : if (fpStopwatch && bStop==1) fpStopwatch->Stop();
2547 :
2548 : // resume to the preceeding guard
2549 0 : fgpCurrent=fpPrec;
2550 0 : }
2551 :
2552 : int AliHLTComponent::AliHLTStopwatchGuard::Hold(const TStopwatch* pSucc)
2553 : {
2554 : // see header file for function documentation
2555 0 : if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Stop();
2556 0 : return fpStopwatch!=pSucc?1:0;
2557 : }
2558 :
2559 : int AliHLTComponent::AliHLTStopwatchGuard::Resume(const TStopwatch* pSucc)
2560 : {
2561 : // see header file for function documentation
2562 0 : if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Start(kFALSE);
2563 0 : return fpStopwatch!=pSucc?1:0;
2564 : }
2565 :
2566 : int AliHLTComponent::SetStopwatch(TObject* pSW, AliHLTStopwatchType type)
2567 : {
2568 : // see header file for function documentation
2569 : int iResult=0;
2570 0 : if (pSW!=NULL && type<kSWTypeCount) {
2571 0 : if (fpStopwatches) {
2572 0 : TObject* pObj=fpStopwatches->At((int)type);
2573 0 : if (pSW==NULL // explicit reset
2574 0 : || pObj==NULL) { // explicit set
2575 0 : fpStopwatches->AddAt(pSW, (int)type);
2576 0 : } else if (pObj!=pSW) {
2577 0 : HLTWarning("stopwatch %d already set, reset first", (int)type);
2578 : iResult=-EBUSY;
2579 0 : }
2580 0 : }
2581 : } else {
2582 : iResult=-EINVAL;
2583 : }
2584 0 : return iResult;
2585 : }
2586 :
2587 : int AliHLTComponent::SetStopwatches(TObjArray* pStopwatches)
2588 : {
2589 : // see header file for function documentation
2590 0 : if (pStopwatches==NULL) return -EINVAL;
2591 :
2592 : int iResult=0;
2593 0 : for (int i=0 ; i<(int)kSWTypeCount && pStopwatches->GetEntriesFast(); i++)
2594 0 : SetStopwatch(pStopwatches->At(i), (AliHLTStopwatchType)i);
2595 : return iResult;
2596 0 : }
2597 :
2598 : AliHLTUInt32_t AliHLTComponent::GetRunNo() const
2599 : {
2600 : // see header file for function documentation
2601 :
2602 : // 2010-02-11 OCDB is now the reliable source for the run number, it is
2603 : // initialized either by aliroot or the external interface depending
2604 : // on the environment. It turned out that the rundescriptor is not set
2605 : // in the aliroot mode, resulting in an invalid run number. However this
2606 : // did not cause problems until now. OCDB initialization has been revised
2607 : // already in 10/2009. This was a remnant.
2608 : // Have to check whether we get rid of the rundescriptor at some point.
2609 0 : if (fpRunDesc==NULL) return AliHLTMisc::Instance().GetCDBRunNo();
2610 0 : if (fpRunDesc->fRunNo!=(unsigned)AliHLTMisc::Instance().GetCDBRunNo()) {
2611 0 : HLTWarning("run number mismatch: ocdb %d run descriptor %d", AliHLTMisc::Instance().GetCDBRunNo(), fpRunDesc->fRunNo);
2612 : }
2613 0 : return fpRunDesc->fRunNo;
2614 0 : }
2615 :
2616 : AliHLTUInt32_t AliHLTComponent::GetRunType() const
2617 : {
2618 : // see header file for function documentation
2619 0 : if (fpRunDesc==NULL) return kAliHLTVoidRunType;
2620 0 : return fpRunDesc->fRunType;
2621 0 : }
2622 :
2623 :
2624 : AliHLTUInt32_t AliHLTComponent::GetTimeStamp() const
2625 : {
2626 : // see header file for function documentation
2627 0 : if (fCurrentEventData.fEventCreation_s < kMaxUInt ) {
2628 0 : return fCurrentEventData.fEventCreation_s;
2629 : }
2630 : // using the actual UTC if the time stamp was not set by the framework
2631 0 : return static_cast<AliHLTUInt32_t>(time(NULL));
2632 0 : }
2633 :
2634 : AliHLTUInt32_t AliHLTComponent::GetPeriodNumber() const
2635 : {
2636 : // see header file for function documentation
2637 0 : return (GetEventId()>>36)&0xfffffff;
2638 : }
2639 :
2640 : AliHLTUInt32_t AliHLTComponent::GetOrbitNumber() const
2641 : {
2642 : // see header file for function documentation
2643 0 : return (GetEventId()>>12)&0xffffff;
2644 : }
2645 :
2646 : AliHLTUInt16_t AliHLTComponent::GetBunchCrossNumber() const
2647 : {
2648 : // see header file for function documentation
2649 0 : return GetEventId()&0xfff;
2650 : }
2651 :
2652 : bool AliHLTComponent::IsDataEvent(AliHLTUInt32_t* pTgt) const
2653 : {
2654 : // see header file for function documentation
2655 0 : if (pTgt) *pTgt=fEventType;
2656 0 : return (fEventType==gkAliEventTypeData ||
2657 0 : fEventType==gkAliEventTypeDataReplay);
2658 : }
2659 :
2660 : int AliHLTComponent::CopyStruct(void* pStruct, unsigned int iStructSize, unsigned int iBlockNo,
2661 : const char* structname, const char* eventname)
2662 : {
2663 : // see header file for function documentation
2664 : int iResult=0;
2665 0 : if (pStruct!=NULL && iStructSize>sizeof(AliHLTUInt32_t)) {
2666 0 : if (fpInputBlocks!=NULL && iBlockNo<fCurrentEventData.fBlockCnt) {
2667 0 : AliHLTUInt32_t* pTgt=(AliHLTUInt32_t*)pStruct;
2668 0 : if (fpInputBlocks[iBlockNo].fPtr && fpInputBlocks[iBlockNo].fSize) {
2669 0 : AliHLTUInt32_t copy=*((AliHLTUInt32_t*)fpInputBlocks[iBlockNo].fPtr);
2670 0 : if (fpInputBlocks[iBlockNo].fSize!=copy) {
2671 0 : HLTWarning("%s event: mismatch of block size (%d) and structure size (%d)", eventname, fpInputBlocks[iBlockNo].fSize, copy);
2672 0 : if (copy>fpInputBlocks[iBlockNo].fSize) copy=fpInputBlocks[iBlockNo].fSize;
2673 : }
2674 0 : if (copy!=iStructSize) {
2675 0 : HLTWarning("%s event: mismatch in %s version (data type version %d)", eventname, structname, ALIHLT_DATA_TYPES_VERSION);
2676 0 : if (copy>iStructSize) {
2677 : copy=iStructSize;
2678 0 : } else {
2679 0 : memset(pTgt, 0, iStructSize);
2680 : }
2681 : }
2682 0 : memcpy(pTgt, fpInputBlocks[iBlockNo].fPtr, copy);
2683 0 : *pTgt=iStructSize;
2684 : iResult=copy;
2685 0 : } else {
2686 0 : HLTWarning("%s event: missing data block", eventname);
2687 : }
2688 0 : } else {
2689 : iResult=-ENODATA;
2690 : }
2691 : } else {
2692 0 : HLTError("invalid struct");
2693 : iResult=-EINVAL;
2694 : }
2695 0 : return iResult;
2696 : }
2697 :
2698 : AliHLTUInt32_t AliHLTComponent::CalculateChecksum(const AliHLTUInt8_t* buffer, int size)
2699 : {
2700 : // see header file for function documentation
2701 : AliHLTUInt32_t remainder = 0;
2702 : const AliHLTUInt8_t crcwidth=(8*sizeof(AliHLTUInt32_t));
2703 : const AliHLTUInt32_t topbit=1 << (crcwidth-1);
2704 : const AliHLTUInt32_t polynomial=0xD8; /* 11011 followed by 0's */
2705 :
2706 : // code from
2707 : // http://www.netrino.com/Embedded-Systems/How-To/CRC-Calculation-C-Code
2708 :
2709 : /*
2710 : * Perform modulo-2 division, a byte at a time.
2711 : */
2712 0 : for (int byte = 0; byte < size; ++byte)
2713 : {
2714 : /*
2715 : * Bring the next byte into the remainder.
2716 : */
2717 0 : remainder ^= (buffer[byte] << (crcwidth - 8));
2718 :
2719 : /*
2720 : * Perform modulo-2 division, a bit at a time.
2721 : */
2722 0 : for (uint8_t bit = 8; bit > 0; --bit)
2723 : {
2724 : /*
2725 : * Try to divide the current data bit.
2726 : */
2727 0 : if (remainder & topbit)
2728 : {
2729 0 : remainder = (remainder << 1) ^ polynomial;
2730 0 : }
2731 : else
2732 : {
2733 : remainder = (remainder << 1);
2734 : }
2735 : }
2736 : }
2737 :
2738 : /*
2739 : * The final remainder is the CRC result.
2740 : */
2741 0 : return (remainder);
2742 : }
2743 :
2744 : int AliHLTComponent::ExtractComponentTableEntry(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size,
2745 : string& retChainId, string& retCompId, string& retCompArgs,
2746 : vector<AliHLTUInt32_t>& parents, int& level)
2747 : {
2748 : // see header file for function documentation
2749 0 : retChainId.clear();
2750 0 : retCompId.clear();
2751 0 : retCompArgs.clear();
2752 0 : parents.clear();
2753 0 : level=-1;
2754 0 : if (!pBuffer || size==0) return 0;
2755 :
2756 0 : const AliHLTComponentTableEntry* pEntry=reinterpret_cast<const AliHLTComponentTableEntry*>(pBuffer);
2757 0 : if (size<8/* the initial size of the structure*/ ||
2758 0 : pEntry==NULL || pEntry->fStructSize<8) return -ENOMSG;
2759 :
2760 0 : if (pEntry->fStructSize!=sizeof(AliHLTComponentTableEntry)) return -EBADF;
2761 0 : level=pEntry->fLevel;
2762 0 : const AliHLTUInt32_t* pParents=reinterpret_cast<const AliHLTUInt32_t*>(pEntry->fBuffer);
2763 0 : const AliHLTUInt8_t* pEnd=pBuffer+size;
2764 :
2765 0 : if (pParents+pEntry->fNofParents>=reinterpret_cast<const AliHLTUInt32_t*>(pEnd)) return -ENODEV;
2766 0 : for (unsigned int i=0; i<pEntry->fNofParents; i++, pParents++) {
2767 0 : parents.push_back(*pParents);
2768 : }
2769 :
2770 0 : const char* pDescription=reinterpret_cast<const char*>(pParents);
2771 0 : if (pDescription+pEntry->fSizeDescription>=reinterpret_cast<const char*>(pEnd) ||
2772 0 : *(pDescription+pEntry->fSizeDescription)!=0) {
2773 0 : return -EBADF;
2774 : }
2775 :
2776 0 : TString descriptor=reinterpret_cast<const char*>(pDescription);
2777 0 : TString chainId;
2778 0 : TString compId;
2779 0 : TString compArgs;
2780 0 : TObjArray* pTokens=descriptor.Tokenize("{");
2781 0 : if (pTokens) {
2782 : int n=0;
2783 0 : if (pTokens->GetEntriesFast()>n) {
2784 0 : retChainId=pTokens->At(n++)->GetName();
2785 : }
2786 0 : if (pTokens->GetEntriesFast()>n) {
2787 0 : compId=pTokens->At(n++)->GetName();
2788 : }
2789 0 : delete pTokens;
2790 0 : }
2791 0 : if (!compId.IsNull() && (pTokens=compId.Tokenize(":"))!=NULL) {
2792 : int n=0;
2793 0 : if (pTokens->GetEntriesFast()>n) {
2794 0 : compId=pTokens->At(n++)->GetName();
2795 : }
2796 0 : if (pTokens->GetEntriesFast()>n) {
2797 0 : compArgs=pTokens->At(n++)->GetName();
2798 : }
2799 0 : delete pTokens;
2800 0 : }
2801 0 : compId.ReplaceAll("}", "");
2802 0 : compArgs.ReplaceAll("}", "");
2803 :
2804 0 : retCompId=compId;
2805 0 : retCompArgs=compArgs;
2806 :
2807 0 : if (retChainId.size()==0) return -ENODATA;
2808 :
2809 0 : return 1;
2810 0 : }
2811 :
2812 : int AliHLTComponent::ExtractTriggerData(
2813 : const AliHLTComponentTriggerData& trigData,
2814 : const AliHLTUInt8_t (**attributes)[gkAliHLTBlockDAttributeCount],
2815 : AliHLTUInt64_t* status,
2816 : AliHLTCDHWrapper* const cdh,
2817 : AliHLTReadoutList* readoutlist,
2818 : bool printErrors
2819 : )
2820 : {
2821 : // see header file for function documentation
2822 :
2823 : // Check that the trigger data structure is the correct size.
2824 0 : if (trigData.fStructSize != sizeof(AliHLTComponentTriggerData))
2825 : {
2826 0 : if (printErrors)
2827 : {
2828 0 : AliHLTLogging log;
2829 0 : log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2830 0 : "Invalid trigger structure size: %d but expected %d.", trigData.fStructSize, sizeof(AliHLTComponentTriggerData)
2831 : );
2832 0 : }
2833 0 : return -ENOENT;
2834 : }
2835 :
2836 : // Get the size of the AliHLTEventTriggerData structure without the readout list part.
2837 : // The way we do this here should also handle memory alignment correctly.
2838 : AliHLTEventTriggerData* dummy = NULL;
2839 : size_t sizeWithoutReadout = (char*)(&dummy->fReadoutList) - (char*)(dummy);
2840 :
2841 : // Check that the trigger data pointer points to data of a size we can handle.
2842 : // Either it is the size of AliHLTEventTriggerData or the size of the old
2843 : // version of AliHLTEventTriggerData using AliHLTEventDDLV0 or V1.
2844 0 : if (trigData.fDataSize != sizeof(AliHLTEventTriggerData) and
2845 0 : trigData.fDataSize != sizeWithoutReadout + sizeof(AliHLTEventDDLV0) and
2846 0 : trigData.fDataSize != sizeWithoutReadout + sizeof(AliHLTEventDDLV1)
2847 : )
2848 : {
2849 0 : if (printErrors)
2850 : {
2851 0 : AliHLTLogging log;
2852 0 : log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2853 0 : "Invalid trigger data size: %d but expected %d.", trigData.fDataSize, sizeof(AliHLTEventTriggerData)
2854 : );
2855 0 : }
2856 0 : return -EBADF;
2857 : }
2858 :
2859 0 : AliHLTEventTriggerData* evtData = reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
2860 0 : assert(evtData != NULL);
2861 :
2862 : // Check that the CDH has the right number of words.
2863 0 : if ( cdh != NULL and
2864 0 : evtData->fCommonHeaderWordCnt != gkAliHLTCommonHeaderCount and
2865 0 : evtData->fCommonHeaderWordCnt != gkAliHLTCommonHeaderCountV2
2866 : )
2867 : {
2868 0 : if (printErrors)
2869 : {
2870 0 : AliHLTLogging log;
2871 0 : log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2872 : "Common Data Header (CDH) has wrong number of data words: %d but expected %d",
2873 0 : evtData->fCommonHeaderWordCnt, gkAliHLTCommonHeaderCount
2874 : );
2875 0 : }
2876 0 : return -EBADMSG;
2877 : }
2878 :
2879 : // Check that the readout list has the correct count of words. i.e. something we can handle,
2880 0 : if (readoutlist != NULL and
2881 0 : evtData->fReadoutList.fCount != (unsigned)gkAliHLTDDLListSizeV0 and
2882 0 : evtData->fReadoutList.fCount != (unsigned)gkAliHLTDDLListSizeV1
2883 : )
2884 : {
2885 0 : if (printErrors)
2886 : {
2887 0 : AliHLTLogging log;
2888 0 : log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2889 : "Readout list structure has wrong number of data words: %d but expected %d",
2890 0 : evtData->fReadoutList.fCount, gkAliHLTDDLListSize
2891 : );
2892 0 : }
2893 0 : return -EPROTO;
2894 : }
2895 :
2896 0 : if (attributes != NULL)
2897 : {
2898 0 : *attributes = &evtData->fAttributes;
2899 0 : }
2900 0 : if (status != NULL)
2901 : {
2902 0 : *status = evtData->fHLTStatus;
2903 0 : }
2904 0 : if (cdh != NULL)
2905 : {
2906 0 : *cdh = &(evtData->fCommonHeader[0]);
2907 0 : }
2908 0 : if (readoutlist != NULL)
2909 : {
2910 0 : *readoutlist = AliHLTReadoutList(evtData->fReadoutList);
2911 0 : }
2912 0 : return 0;
2913 0 : }
2914 :
2915 : AliHLTUInt32_t AliHLTComponent::ExtractEventTypeFromCDH(const AliHLTCDHWrapper* const cdh)
2916 : {
2917 : // see header file for function documentation
2918 0 : UChar_t l1msg = cdh->GetL1TriggerMessage();
2919 0 : if ((l1msg & 0x1) == 0x0) return gkAliEventTypeData;
2920 : // The L2SwC bit must be one if we got here, i.e. l1msg & 0x1 == 0x1.
2921 0 : if (((l1msg >> 2) & 0xF) == 0xE) return gkAliEventTypeStartOfRun;
2922 0 : if (((l1msg >> 2) & 0xF) == 0xF) return gkAliEventTypeEndOfRun;
2923 : // Check the C1T bit to see if this is a calibration event,
2924 : // if not then it must be some other software trigger event.
2925 0 : if (((l1msg >> 6) & 0x1) == 0x1) return gkAliEventTypeCalibration;
2926 0 : return gkAliEventTypeSoftware;
2927 0 : }
2928 :
2929 : int AliHLTComponent::LoggingVarargs(AliHLTComponentLogSeverity severity,
2930 : const char* originClass, const char* originFunc,
2931 : const char* file, int line, ... ) const
2932 : {
2933 : // see header file for function documentation
2934 : int iResult=0;
2935 :
2936 0 : va_list args;
2937 0 : va_start(args, line);
2938 :
2939 : // logging function needs to be const in order to be called from const member functions
2940 : // without problems. But at this point we face the problem with virtual members which
2941 : // are not necessarily const.
2942 : AliHLTComponent* nonconst=const_cast<AliHLTComponent*>(this);
2943 0 : AliHLTLogging::SetLogString(this, ", %p", "%s (%s_pfmt_): ",
2944 0 : fChainId[0]!=0?fChainId.c_str():nonconst->GetComponentID(),
2945 0 : nonconst->GetComponentID());
2946 0 : iResult=SendMessage(severity, originClass, originFunc, file, line, AliHLTLogging::BuildLogString(NULL, args, true /*append*/));
2947 0 : va_end(args);
2948 :
2949 0 : return iResult;
2950 0 : }
2951 :
2952 : TUUID AliHLTComponent::GenerateGUID()
2953 : {
2954 : // Generates a globally unique identifier.
2955 :
2956 : // Start by creating a new UUID. We cannot use the one automatically generated
2957 : // by ROOT because the algorithm used will not guarantee unique IDs when generating
2958 : // these UUIDs at a high rate in parallel.
2959 0 : TUUID uuid;
2960 : // We then use the generated UUID to form part of the random number seeds which
2961 : // will be used to generate a proper random UUID. For good measure we use a MD5
2962 : // hash also. Note that we want to use the TUUID class because it will combine the
2963 : // host address information into the UUID. Using gSystem->GetHostByName() apparently
2964 : // can cause problems on Windows machines with a firewall, because it always tries
2965 : // to contact a DNS. The TUUID class handles this case appropriately.
2966 0 : union
2967 : {
2968 : UChar_t buf[16];
2969 : UShort_t word[8];
2970 : UInt_t dword[4];
2971 : };
2972 0 : uuid.GetUUID(buf);
2973 0 : TMD5 md5;
2974 0 : md5.Update(buf, sizeof(buf));
2975 0 : TMD5 md52 = md5;
2976 0 : md5.Final(buf);
2977 0 : dword[0] += gSystem->GetUid();
2978 0 : dword[1] += gSystem->GetGid();
2979 0 : dword[2] += gSystem->GetPid();
2980 0 : for (int i = 0; i < 4; ++i)
2981 : {
2982 0 : gRandom->SetSeed(dword[i]);
2983 0 : dword[i] = gRandom->Integer(0xFFFFFFFF);
2984 : }
2985 0 : md52.Update(buf, sizeof(buf));
2986 0 : md52.Final(buf);
2987 : // To keep to the standard we need to set the version and reserved bits.
2988 0 : word[3] = (word[3] & 0x0FFF) | 0x4000;
2989 0 : buf[8] = (buf[8] & 0x3F) | 0x80;
2990 :
2991 : // Create the name of the new class and file.
2992 0 : char uuidstr[64];
2993 0 : sprintf(uuidstr, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
2994 0 : dword[0], word[2], word[3], buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]
2995 : );
2996 :
2997 0 : uuid.SetUUID(uuidstr);
2998 : return uuid;
2999 0 : }
3000 :
3001 : int AliHLTComponent::ScanECSParam(const char* ecsParam)
3002 : {
3003 : // see header file for function documentation
3004 :
3005 : // format of the parameter string from ECS
3006 : // <command>;<parameterkey>=<parametervalue>;<parameterkey>=<parametervalue>;...
3007 : // search for a subset of the parameterkeys
3008 : // RUN_TYPE=
3009 : // RUN_NUMBER=
3010 : // HLT_IN_DDL_LIST=
3011 : // CTP_TRIGGER_CLASS=
3012 : // DATA_FORMAT_VERSION=
3013 : // BEAM_TYPE=
3014 : // HLT_OUT_DDL_LIST=
3015 : // HLT_TRIGGER_CODE=
3016 : // DETECTOR_LIST=
3017 : // HLT_MODE=
3018 : // The command apears not to be sent by the online framework
3019 : int iResult=0;
3020 0 : TString string=ecsParam;
3021 0 : TObjArray* parameter=string.Tokenize(";");
3022 0 : if (parameter) {
3023 0 : for (int i=0; i<parameter->GetEntriesFast(); i++) {
3024 0 : TString entry=parameter->At(i)->GetName();
3025 : HLTDebug("scanning ECS entry: %s", entry.Data());
3026 0 : TObjArray* entryParams=entry.Tokenize("=");
3027 0 : if (entryParams) {
3028 0 : if (entryParams->GetEntriesFast()>1) {
3029 0 : if ((((TObjString*)entryParams->At(0))->GetString()).CompareTo("CTP_TRIGGER_CLASS")==0) {
3030 0 : int result=InitCTPTriggerClasses(entryParams->At(1)->GetName());
3031 0 : if (iResult>=0 && result<0) iResult=result;
3032 0 : } else {
3033 : // TODO: scan the other parameters
3034 : // e.g. consistency check of run number
3035 : }
3036 : }
3037 0 : delete entryParams;
3038 : }
3039 0 : }
3040 0 : delete parameter;
3041 : }
3042 :
3043 : return iResult;
3044 0 : }
3045 :
3046 : int AliHLTComponent::SetupCTPData()
3047 : {
3048 : // see header file for function documentation
3049 0 : if (fpCTPData) delete fpCTPData;
3050 0 : fpCTPData=new AliHLTCTPData;
3051 0 : if (!fpCTPData) return -ENOMEM;
3052 0 : return 0;
3053 0 : }
3054 :
3055 : int AliHLTComponent::InitCTPTriggerClasses(const char* ctpString)
3056 : {
3057 : // see header file for function documentation
3058 0 : if (!fpCTPData) return 0; // silently accept as the component has to announce that it want's the CTP info
3059 0 : return fpCTPData->InitCTPTriggerClasses(ctpString);
3060 0 : }
3061 :
3062 : bool AliHLTComponent::EvaluateCTPTriggerClass(const char* expression, AliHLTComponentTriggerData& trigData) const
3063 : {
3064 : // see header file for function documentation
3065 0 : if (!fpCTPData) {
3066 : static bool bWarningThrown=false;
3067 0 : if (!bWarningThrown) HLTError("Trigger classes not initialized, use SetupCTPData from DoInit()");
3068 0 : bWarningThrown=true;
3069 0 : return false;
3070 : }
3071 :
3072 0 : return fpCTPData->EvaluateCTPTriggerClass(expression, trigData);
3073 0 : }
3074 :
3075 : int AliHLTComponent::CheckCTPTrigger(const char* name) const
3076 : {
3077 : // see header file for function documentation
3078 0 : if (!fpCTPData) {
3079 : static bool bWarningThrown=false;
3080 0 : if (!bWarningThrown) HLTError("Trigger classes not initialized, use SetupCTPData from DoInit()");
3081 0 : bWarningThrown=true;
3082 0 : return false;
3083 : }
3084 :
3085 0 : return fpCTPData->CheckTrigger(name);
3086 0 : }
3087 :
3088 : Double_t AliHLTComponent::GetBz()
3089 : {
3090 : // Returns Bz.
3091 0 : return AliHLTMisc::Instance().GetBz();
3092 : }
3093 :
3094 : Double_t AliHLTComponent::GetBz(const Double_t *r)
3095 : {
3096 : // Returns Bz (kG) at the point "r" .
3097 0 : return AliHLTMisc::Instance().GetBz(r);
3098 : }
3099 :
3100 : void AliHLTComponent::GetBxByBz(const Double_t r[3], Double_t b[3])
3101 : {
3102 : // Returns Bx, By and Bz (kG) at the point "r" .
3103 0 : AliHLTMisc::Instance().GetBxByBz(r, b);
3104 0 : }
3105 :
3106 : int AliHLTComponent::UpdateSchema(TCollection* listOfStreamerInfos)
3107 : {
3108 : //update the schema cache with the contents of the list from AliHLTMessage
3109 0 : TIter nextInfo(listOfStreamerInfos);
3110 : TStreamerInfo* info=NULL;
3111 0 : while ((info = static_cast<TStreamerInfo*>(nextInfo()))) {
3112 0 : const char* infoName = info->GetName();
3113 0 : if (!fSchema.FindObject(infoName)) {
3114 0 : fSchema.Add(info);
3115 0 : listOfStreamerInfos->Remove(info);
3116 0 : fSchemaUpdated=kTRUE;
3117 0 : }
3118 : }
3119 : return 0;
3120 0 : }
3121 :
3122 : int AliHLTComponent::UpdateSchema(const TCollection* listOfStreamerInfos)
3123 : {
3124 : //update the schema cache with the contents of the list from AliHLTMessage
3125 0 : TIter nextInfo(listOfStreamerInfos);
3126 : TStreamerInfo* info=NULL;
3127 0 : while ((info = static_cast<TStreamerInfo*>(nextInfo()))) {
3128 0 : const char* infoName = info->GetName();
3129 0 : if (!fSchema.FindObject(infoName)) {
3130 0 : fSchema.Add(info);
3131 0 : fSchemaUpdated=kTRUE;
3132 0 : }
3133 : }
3134 : return 0;
3135 0 : }
3136 :
3137 : int AliHLTComponent::PushBackSchema()
3138 : {
3139 : int rc = 0;
3140 : //this will push back the block with root streamers only if anything new was added
3141 0 : if (fSchemaUpdated)
3142 : {
3143 0 : rc = PushBack(&fSchema, kAliHLTDataTypeStreamerInfo|kAliHLTDataOriginHLT, 0);
3144 0 : fSchemaUpdated=kFALSE;
3145 0 : }
3146 0 : return rc;
3147 : }
3148 :
|