8714af131f0f1324132a89776f17c19451e1e54a
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTComponent.cxx
1 // $Id$
2
3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project        * 
5 //* ALICE Experiment at CERN, All rights reserved.                         *
6 //*                                                                        *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
8 //*                  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
25 #if __GNUC__>= 3
26 using namespace std;
27 #endif
28
29 //#include "AliHLTStdIncludes.h"
30 #include "AliHLTComponent.h"
31 #include "AliHLTComponentHandler.h"
32 #include "AliHLTMessage.h"
33 #include "TString.h"
34 #include "TMath.h"
35 #include "TObjArray.h"
36 #include "TObjectTable.h"
37 #include "TClass.h"
38 #include "TStopwatch.h"
39 #include "AliHLTMemoryFile.h"
40 #include "AliHLTMisc.h"
41 #include <cassert>
42
43 /** ROOT macro for the implementation of ROOT specific class methods */
44 ClassImp(AliHLTComponent);
45
46 /** stopwatch macro using the stopwatch guard */
47 #define ALIHLTCOMPONENT_STOPWATCH(type) AliHLTStopwatchGuard swguard(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)type)):NULL)
48 //#define ALIHLTCOMPONENT_STOPWATCH(type) 
49
50 /** stopwatch macro for operations of the base class */
51 #define ALIHLTCOMPONENT_BASE_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWBase)
52 /** stopwatch macro for operations of the detector algorithm (DA) */
53 #define ALIHLTCOMPONENT_DA_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWDA)
54
55 AliHLTComponent::AliHLTComponent()
56   :
57   fEnvironment(),
58   fCurrentEvent(0),
59   fEventCount(-1),
60   fFailedEvents(0),
61   fCurrentEventData(),
62   fpInputBlocks(NULL),
63   fCurrentInputBlock(-1),
64   fSearchDataType(kAliHLTVoidDataType),
65   fClassName(),
66   fpInputObjects(NULL),
67   fpOutputBuffer(NULL),
68   fOutputBufferSize(0),
69   fOutputBufferFilled(0),
70   fOutputBlocks(),
71   fpStopwatches(new TObjArray(kSWTypeCount)),
72   fMemFiles(),
73   fpRunDesc(NULL),
74   fpDDLList(NULL),
75   fCDBSetRunNoFunc(false),
76   fChainId()
77 {
78   // see header file for class documentation
79   // or
80   // refer to README to build package
81   // or
82   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
83   memset(&fEnvironment, 0, sizeof(AliHLTComponentEnvironment));
84   if (fgpComponentHandler)
85     fgpComponentHandler->ScheduleRegister(this);
86   //SetLocalLoggingLevel(kHLTLogDefault);
87 }
88
89 AliHLTComponent::~AliHLTComponent()
90 {
91   // see header file for function documentation
92   CleanupInputObjects();
93   if (fpStopwatches!=NULL) delete fpStopwatches;
94   fpStopwatches=NULL;
95   AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
96   while (element!=fMemFiles.end()) {
97     if (*element) {
98       if ((*element)->IsClosed()==0) {
99         HLTWarning("memory file has not been closed, possible data loss or incomplete buffer");
100         // close but do not flush as we dont know whether the buffer is still valid
101         (*element)->CloseMemoryFile(0);
102       }
103       delete *element;
104       *element=NULL;
105     }
106     element++;
107   }
108 }
109
110 AliHLTComponentHandler* AliHLTComponent::fgpComponentHandler=NULL;
111
112 int AliHLTComponent::SetGlobalComponentHandler(AliHLTComponentHandler* pCH, int bOverwrite) 
113 {
114   // see header file for function documentation
115   int iResult=0;
116   if (fgpComponentHandler==NULL || bOverwrite!=0)
117     fgpComponentHandler=pCH;
118   else
119     iResult=-EPERM;
120   return iResult;
121 }
122
123 int AliHLTComponent::UnsetGlobalComponentHandler() 
124 {
125   // see header file for function documentation
126   return SetGlobalComponentHandler(NULL,1);
127 }
128
129 int AliHLTComponent::Init( AliHLTComponentEnvironment* environ, void* environParam, int argc, const char** argv )
130 {
131   // see header file for function documentation
132   HLTLogKeyword(GetComponentID());
133   int iResult=0;
134   if (environ) {
135     memcpy(&fEnvironment, environ, sizeof(AliHLTComponentEnvironment));
136     fEnvironment.fParam=environParam;
137   }
138   const char** pArguments=NULL;
139   int iNofChildArgs=0;
140   TString argument="";
141   int bMissingParam=0;
142   if (argc>0) {
143     pArguments=new const char*[argc];
144     if (pArguments) {
145       for (int i=0; i<argc && iResult>=0; i++) {
146         argument=argv[i];
147         if (argument.IsNull()) continue;
148
149         // benchmark
150         if (argument.CompareTo("benchmark")==0) {
151
152           // loglevel
153         } else if (argument.CompareTo("loglevel")==0) {
154           if ((bMissingParam=(++i>=argc))) break;
155           TString parameter(argv[i]);
156           parameter.Remove(TString::kLeading, ' '); // remove all blanks
157           if (parameter.BeginsWith("0x") &&
158               parameter.Replace(0,2,"",0).IsHex()) {
159             AliHLTComponentLogSeverity loglevel=kHLTLogNone;
160             sscanf(parameter.Data(),"%x", (unsigned int*)&loglevel);
161             SetLocalLoggingLevel(loglevel);
162           } else {
163             HLTError("wrong parameter for argument %s, hex number expected", argument.Data());
164             iResult=-EINVAL;
165           }
166         } else {
167           pArguments[iNofChildArgs++]=argv[i];
168         }
169       }
170     } else {
171       iResult=-ENOMEM;
172     }
173   }
174   if (bMissingParam) {
175     HLTError("missing parameter for argument %s", argument.Data());
176     iResult=-EINVAL;
177   }
178   if (iResult>=0) {
179     iResult=DoInit(iNofChildArgs, pArguments);
180   }
181   if (iResult>=0) fEventCount=0;
182   if (pArguments) delete [] pArguments;
183   return iResult;
184 }
185
186 int AliHLTComponent::Deinit()
187 {
188   // see header file for function documentation
189   HLTLogKeyword(GetComponentID());
190   int iResult=0;
191   iResult=DoDeinit();
192   if (fpRunDesc) {
193     HLTWarning("did not receive EOR for run %d", fpRunDesc->fRunNo);
194     AliHLTRunDesc* pRunDesc=fpRunDesc;
195     fpRunDesc=NULL;
196     delete pRunDesc;
197   }
198   fEventCount=0;
199   return iResult;
200 }
201
202 int AliHLTComponent::InitCDB(const char* cdbPath, AliHLTComponentHandler* pHandler)
203 {
204   // see header file for function documentation
205   int iResult=0;
206   if (cdbPath && pHandler) {
207   // I have to think about separating the library handling from the
208   // component handler. Requiring the component hanlder here is not
209   // the cleanest solution.
210   // We presume the library already to be loaded
211   // find the symbol
212   AliHLTMiscInitCDB_t pFunc=(AliHLTMiscInitCDB_t)pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_INIT_CDB);
213   if (pFunc) {
214     TString path=cdbPath;
215     // very temporary fix, have to check for other formats
216     if (!path.BeginsWith("local://")) {
217       path="local://";
218       path+=cdbPath;
219     }
220     if ((iResult=(*pFunc)(path.Data()))>=0) {
221       if (!(fCDBSetRunNoFunc=pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_SET_CDB_RUNNO))) {
222         Message(NULL, kHLTLogWarning, "AliHLTComponent::InitCDB", "init CDB",
223                 "can not find function to set CDB run no");
224       }
225     }
226   } else {
227     Message(NULL, kHLTLogError, "AliHLTComponent::InitCDB", "init CDB",
228             "can not find initialization function");
229     iResult=-ENOSYS;
230   }
231   } else {
232     iResult=-EINVAL;
233   }
234   return iResult;
235 }
236
237 int AliHLTComponent::SetCDBRunNo(int runNo)
238 {
239   // see header file for function documentation
240   if (!fCDBSetRunNoFunc) return 0;
241   return (*((AliHLTMiscSetCDBRunNo_t)fCDBSetRunNoFunc))(runNo);
242 }
243
244 int AliHLTComponent::DoInit( int /*argc*/, const char** /*argv*/)
245 {
246   // default implementation, childs can overload
247   HLTLogKeyword("dummy");
248   return 0;
249 }
250
251 int AliHLTComponent::DoDeinit()
252 {
253   // default implementation, childs can overload
254   HLTLogKeyword("dummy");
255   return 0;
256 }
257
258 int AliHLTComponent::Reconfigure(const char* /*cdbEntry*/, const char* /*chainId*/)
259 {
260   // default implementation, childs can overload
261   HLTLogKeyword("dummy");
262   return 0;
263 }
264
265 int AliHLTComponent::ReadPreprocessorValues(const char* /*modules*/)
266 {
267   // default implementation, childs can overload
268   HLTLogKeyword("dummy");
269   return 0;
270 }
271
272 int AliHLTComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& /*tgtList*/)
273 {
274   // default implementation, childs can overload
275   HLTLogKeyword("dummy");
276   return 0;
277 }
278
279 void AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, char output[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2] ) const
280 {
281   // see header file for function documentation
282   memset( output, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
283   strncat( output, type.fOrigin, kAliHLTComponentDataTypefOriginSize );
284   strcat( output, ":" );
285   strncat( output, type.fID, kAliHLTComponentDataTypefIDsize );
286 }
287
288 string AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, int mode)
289 {
290   // see header file for function documentation
291   string out("");
292
293   if (mode==2) {
294     int i=0;
295     char tmp[8];
296     for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
297       sprintf(tmp, "'%d", type.fOrigin[i]);
298       out+=tmp;
299     }
300     out+="':'";
301     for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
302       sprintf(tmp, "%d'", type.fID[i]);
303       out+=tmp;
304     }
305     return out;
306   }
307
308   if (mode==1) {
309     int i=0;
310     char tmp[8];
311     for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
312       unsigned char* puc=(unsigned char*)type.fOrigin;
313       if ((puc[i])<32)
314         sprintf(tmp, "'\\%x", type.fOrigin[i]);
315       else
316         sprintf(tmp, "'%c", type.fOrigin[i]);
317       out+=tmp;
318     }
319     out+="':'";
320     for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
321       unsigned char* puc=(unsigned char*)type.fID;
322       if (puc[i]<32)
323         sprintf(tmp, "\\%x'", type.fID[i]);
324       else
325         sprintf(tmp, "%c'", type.fID[i]);
326       out+=tmp;
327     }
328     return out;
329   }
330
331   if (type==kAliHLTVoidDataType) {
332     out="VOID:VOID";
333   } else {
334     // some gymnastics in order to avoid a '0' which is part of either or both
335     // ID and origin terminating the whole string. Unfortunately, string doesn't
336     // stop appending at the '0' if the number of elements to append was 
337     // explicitely specified
338     string tmp("");
339     tmp.append(type.fOrigin, kAliHLTComponentDataTypefOriginSize);
340     out.append(tmp.c_str());
341     out.append(":");
342     tmp="";
343     tmp.append(type.fID, kAliHLTComponentDataTypefIDsize);
344     out.append(tmp.c_str());
345   }
346   return out;
347 }
348
349
350 void* AliHLTComponent::AllocMemory( unsigned long size ) 
351 {
352   // see header file for function documentation
353   if (fEnvironment.fAllocMemoryFunc)
354     return (*fEnvironment.fAllocMemoryFunc)(fEnvironment.fParam, size );
355   HLTFatal("no memory allocation handler registered");
356   return NULL;
357 }
358
359 int AliHLTComponent::MakeOutputDataBlockList( const AliHLTComponentBlockDataList& blocks, AliHLTUInt32_t* blockCount,
360                                               AliHLTComponentBlockData** outputBlocks ) 
361 {
362   // see header file for function documentation
363     if ( blockCount==NULL || outputBlocks==NULL )
364         return -EFAULT;
365     AliHLTUInt32_t count = blocks.size();
366     if ( !count )
367         {
368         *blockCount = 0;
369         *outputBlocks = NULL;
370         return 0;
371         }
372     *outputBlocks = reinterpret_cast<AliHLTComponentBlockData*>( AllocMemory( sizeof(AliHLTComponentBlockData)*count ) );
373     if ( !*outputBlocks )
374         return -ENOMEM;
375     for ( unsigned long i = 0; i < count; i++ ) {
376         (*outputBlocks)[i] = blocks[i];
377         if (MatchExactly(blocks[i].fDataType, kAliHLTAnyDataType)) {
378           (*outputBlocks)[i].fDataType=GetOutputDataType();
379           /* data type was set to the output data type by the PubSub AliRoot
380              Wrapper component, if data type of the block was ********:****.
381              Now handled by the component base class in order to have same
382              behavior when running embedded in AliRoot
383           memset((*outputBlocks)[i].fDataType.fID, '*', kAliHLTComponentDataTypefIDsize);
384           memset((*outputBlocks)[i].fDataType.fOrigin, '*', kAliHLTComponentDataTypefOriginSize);
385           */
386         }
387     }
388     *blockCount = count;
389     return 0;
390
391 }
392
393 int AliHLTComponent::GetEventDoneData( unsigned long size, AliHLTComponentEventDoneData** edd ) 
394 {
395   // see header file for function documentation
396   if (fEnvironment.fGetEventDoneDataFunc)
397     return (*fEnvironment.fGetEventDoneDataFunc)(fEnvironment.fParam, fCurrentEvent, size, edd );
398   return -ENOSYS;
399 }
400
401 int AliHLTComponent::FindMatchingDataTypes(AliHLTComponent* pConsumer, AliHLTComponentDataTypeList* tgtList) 
402 {
403   // see header file for function documentation
404   int iResult=0;
405   if (pConsumer) {
406     AliHLTComponentDataTypeList itypes;
407     AliHLTComponentDataTypeList otypes;
408     otypes.push_back(GetOutputDataType());
409     if (otypes[0]==kAliHLTMultipleDataType) {
410       otypes.clear();
411       int count=0;
412       if ((count=GetOutputDataTypes(otypes))>0) {
413       } else if (GetComponentType()!=kSink) {
414         HLTWarning("component %s indicates multiple output data types but GetOutputDataTypes returns %d", GetComponentID(), count);
415       }
416     }
417     ((AliHLTComponent*)pConsumer)->GetInputDataTypes(itypes);
418     AliHLTComponentDataTypeList::iterator itype=itypes.begin();
419     while (itype!=itypes.end()) {
420       //PrintDataTypeContent((*itype), "consumer \'%s\'");
421       AliHLTComponentDataTypeList::iterator otype=otypes.begin();
422       while (otype!=otypes.end() && (*itype)!=(*otype)) otype++;
423       //if (otype!=otypes.end()) PrintDataTypeContent(*otype, "publisher \'%s\'");
424       if (otype!=otypes.end()) {
425         if (tgtList) tgtList->push_back(*itype);
426         iResult++;
427       }
428       itype++;
429     }
430   } else {
431     iResult=-EINVAL;
432   }
433   return iResult;
434 }
435
436 void AliHLTComponent::PrintDataTypeContent(AliHLTComponentDataType& dt, const char* format)
437 {
438   // see header file for function documentation
439   const char* fmt="\'%s\'";
440   if (format) fmt=format;
441   AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, Form(fmt, (DataType2Text(dt)).c_str()));
442   AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, 
443                          Form("%x %x %x %x %x %x %x %x : %x %x %x %x", 
444                               dt.fID[0],
445                               dt.fID[1],
446                               dt.fID[2],
447                               dt.fID[3],
448                               dt.fID[4],
449                               dt.fID[5],
450                               dt.fID[6],
451                               dt.fID[7],
452                               dt.fOrigin[0],
453                               dt.fOrigin[1],
454                               dt.fOrigin[2],
455                               dt.fOrigin[3]));
456 }
457
458 void AliHLTComponent::FillBlockData( AliHLTComponentBlockData& blockData )
459 {
460   // see header file for function documentation
461   blockData.fStructSize = sizeof(blockData);
462   FillShmData( blockData.fShmKey );
463   blockData.fOffset = ~(AliHLTUInt32_t)0;
464   blockData.fPtr = NULL;
465   blockData.fSize = 0;
466   FillDataType( blockData.fDataType );
467   blockData.fSpecification = kAliHLTVoidDataSpec;
468 }
469
470 void AliHLTComponent::FillShmData( AliHLTComponentShmData& shmData )
471 {
472   // see header file for function documentation
473   shmData.fStructSize = sizeof(shmData);
474   shmData.fShmType = gkAliHLTComponentInvalidShmType;
475   shmData.fShmID = gkAliHLTComponentInvalidShmID;
476 }
477
478 void AliHLTComponent::FillDataType( AliHLTComponentDataType& dataType )
479 {
480   // see header file for function documentation
481   dataType=kAliHLTAnyDataType;
482 }
483
484 void AliHLTComponent::CopyDataType(AliHLTComponentDataType& tgtdt, const AliHLTComponentDataType& srcdt) 
485 {
486   // see header file for function documentation
487   memcpy(&tgtdt.fID[0], &srcdt.fID[0], kAliHLTComponentDataTypefIDsize);
488   memcpy(&tgtdt.fOrigin[0], &srcdt.fOrigin[0], kAliHLTComponentDataTypefOriginSize);
489 }
490
491 void AliHLTComponent::SetDataType(AliHLTComponentDataType& tgtdt, const char* id, const char* origin) 
492 {
493   // see header file for function documentation
494   tgtdt.fStructSize=sizeof(AliHLTComponentDataType);
495   if (id) {
496     memset(&tgtdt.fID[0], 0, kAliHLTComponentDataTypefIDsize);
497     strncpy(&tgtdt.fID[0], id, strlen(id)<(size_t)kAliHLTComponentDataTypefIDsize?strlen(id):kAliHLTComponentDataTypefIDsize);
498   }
499   if (origin) {
500     memset(&tgtdt.fOrigin[0], 0, kAliHLTComponentDataTypefOriginSize);
501     strncpy(&tgtdt.fOrigin[0], origin, strlen(origin)<(size_t)kAliHLTComponentDataTypefOriginSize?strlen(origin):kAliHLTComponentDataTypefOriginSize);
502   }
503 }
504
505 void AliHLTComponent::SetDataType(AliHLTComponentDataType& dt, AliHLTUInt64_t id, AliHLTUInt32_t origin)
506 {
507   // see header file for function documentation
508   dt.fStructSize=sizeof(AliHLTComponentDataType);
509   assert(kAliHLTComponentDataTypefIDsize==sizeof(id));
510   assert(kAliHLTComponentDataTypefOriginSize==sizeof(origin));
511   memcpy(&dt.fID, &id, kAliHLTComponentDataTypefIDsize);
512   memcpy(&dt.fOrigin, &origin, kAliHLTComponentDataTypefOriginSize);
513 }
514
515 void AliHLTComponent::FillEventData(AliHLTComponentEventData& evtData)
516 {
517   // see header file for function documentation
518   memset(&evtData, 0, sizeof(AliHLTComponentEventData));
519   evtData.fStructSize=sizeof(AliHLTComponentEventData);
520 }
521
522 void AliHLTComponent::PrintComponentDataTypeInfo(const AliHLTComponentDataType& dt) 
523 {
524   // see header file for function documentation
525   TString msg;
526   msg.Form("AliHLTComponentDataType(%d): ID=\"", dt.fStructSize);
527   for ( int i = 0; i < kAliHLTComponentDataTypefIDsize; i++ ) {
528    if (dt.fID[i]!=0) msg+=dt.fID[i];
529    else msg+="\\0";
530   }
531   msg+="\" Origin=\"";
532   for ( int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++ ) {
533    if (dt.fOrigin[i]!=0) msg+=dt.fOrigin[i];
534    else msg+="\\0";
535   }
536   msg+="\"";
537   AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, msg.Data());
538 }
539
540 int AliHLTComponent::GetEventCount() const
541 {
542   // see header file for function documentation
543   return fEventCount;
544 }
545
546 int AliHLTComponent::IncrementEventCounter()
547 {
548   // see header file for function documentation
549   if (fEventCount>=0) fEventCount++;
550   return fEventCount;
551 }
552
553 int AliHLTComponent::GetNumberOfInputBlocks() const
554 {
555   // see header file for function documentation
556   if (fpInputBlocks!=NULL) {
557     return fCurrentEventData.fBlockCnt;
558   }
559   return 0;
560 }
561
562 const TObject* AliHLTComponent::GetFirstInputObject(const AliHLTComponentDataType& dt,
563                                                     const char* classname,
564                                                     int bForce)
565 {
566   // see header file for function documentation
567   ALIHLTCOMPONENT_BASE_STOPWATCH();
568   fSearchDataType=dt;
569   if (classname) fClassName=classname;
570   else fClassName.clear();
571   int idx=FindInputBlock(fSearchDataType, 0, 1);
572   TObject* pObj=NULL;
573   if (idx>=0) {
574     HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(dt).c_str());
575     if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
576       fCurrentInputBlock=idx;
577     } else {
578     }
579   }
580   return pObj;
581 }
582
583 const TObject* AliHLTComponent::GetFirstInputObject(const char* dtID, 
584                                                     const char* dtOrigin,
585                                                     const char* classname,
586                                                     int         bForce)
587 {
588   // see header file for function documentation
589   ALIHLTCOMPONENT_BASE_STOPWATCH();
590   AliHLTComponentDataType dt;
591   SetDataType(dt, dtID, dtOrigin);
592   return GetFirstInputObject(dt, classname, bForce);
593 }
594
595 const TObject* AliHLTComponent::GetNextInputObject(int bForce)
596 {
597   // see header file for function documentation
598   ALIHLTCOMPONENT_BASE_STOPWATCH();
599   int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1, 1);
600   //HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(fSearchDataType).c_str());
601   TObject* pObj=NULL;
602   if (idx>=0) {
603     if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
604       fCurrentInputBlock=idx;
605     }
606   }
607   return pObj;
608 }
609
610 int AliHLTComponent::FindInputBlock(const AliHLTComponentDataType& dt, int startIdx, int bObject) const
611 {
612   // see header file for function documentation
613   int iResult=-ENOENT;
614   if (fpInputBlocks!=NULL) {
615     int idx=startIdx<0?0:startIdx;
616     for ( ; (UInt_t)idx<fCurrentEventData.fBlockCnt && iResult==-ENOENT; idx++) {
617       if (dt!=fpInputBlocks[idx].fDataType) continue;
618
619       if (bObject!=0) {
620         if (fpInputBlocks[idx].fPtr==NULL) continue;
621         AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
622         if (firstWord!=fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) continue;
623       }
624       iResult=idx;
625     }
626   }
627   return iResult;
628 }
629
630 TObject* AliHLTComponent::CreateInputObject(int idx, int bForce)
631 {
632   // see header file for function documentation
633   TObject* pObj=NULL;
634   if (fpInputBlocks!=NULL) {
635     if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
636       if (fpInputBlocks[idx].fPtr) {
637         AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
638         if (firstWord==fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) {
639           HLTDebug("create object from block %d size %d", idx, fpInputBlocks[idx].fSize);
640           AliHLTMessage msg(fpInputBlocks[idx].fPtr, fpInputBlocks[idx].fSize);
641           TClass* objclass=msg.GetClass();
642           pObj=msg.ReadObject(objclass);
643           if (pObj && objclass) {
644             HLTDebug("object %p type %s created", pObj, objclass->GetName());
645           } else {
646           }
647           //} else {
648         } else if (bForce!=0) {
649           HLTError("size mismatch: block size %d, indicated %d", fpInputBlocks[idx].fSize, firstWord+sizeof(AliHLTUInt32_t));
650         }
651       } else {
652         HLTFatal("block descriptor empty");
653       }
654     } else {
655       HLTError("index %d out of range %d", idx, fCurrentEventData.fBlockCnt);
656     }
657   } else {
658     HLTError("no input blocks available");
659   }
660   
661   return pObj;
662 }
663
664 TObject* AliHLTComponent::GetInputObject(int idx, const char* /*classname*/, int bForce)
665 {
666   // see header file for function documentation
667   if (fpInputObjects==NULL) {
668     fpInputObjects=new TObjArray(fCurrentEventData.fBlockCnt);
669   }
670   TObject* pObj=NULL;
671   if (fpInputObjects) {
672     pObj=fpInputObjects->At(idx);
673     if (pObj==NULL) {
674       pObj=CreateInputObject(idx, bForce);
675       if (pObj) {
676         fpInputObjects->AddAt(pObj, idx);
677       }
678     }
679   } else {
680     HLTFatal("memory allocation failed: TObjArray of size %d", fCurrentEventData.fBlockCnt);
681   }
682   return pObj;
683 }
684
685 int AliHLTComponent::CleanupInputObjects()
686 {
687   // see header file for function documentation
688   if (!fpInputObjects) return 0;
689   TObjArray* array=fpInputObjects;
690   fpInputObjects=NULL;
691   for (int i=0; i<array->GetEntries(); i++) {
692     TObject* pObj=array->At(i);
693     // grrr, garbage collection strikes back: When read via AliHLTMessage
694     // (CreateInputObject), and written to a TFile afterwards, the
695     // TFile::Close calls ROOOT's garbage collection. No clue why the
696     // object ended up in the key list and needs to be deleted
697     if (pObj && gObjectTable->PtrIsValid(pObj)) delete pObj;
698   }
699   delete array;
700   return 0;
701 }
702
703 AliHLTComponentDataType AliHLTComponent::GetDataType(const TObject* pObject)
704 {
705   // see header file for function documentation
706   ALIHLTCOMPONENT_BASE_STOPWATCH();
707   AliHLTComponentDataType dt=kAliHLTVoidDataType;
708   int idx=fCurrentInputBlock;
709   if (pObject) {
710     if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
711     } else {
712       HLTError("unknown object %p", pObject);
713     }
714   }
715   if (idx>=0) {
716     if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
717       dt=fpInputBlocks[idx].fDataType;
718     } else {
719       HLTFatal("severe internal error, index out of range");
720     }
721   }
722   return dt;
723 }
724
725 AliHLTUInt32_t AliHLTComponent::GetSpecification(const TObject* pObject)
726 {
727   // see header file for function documentation
728   ALIHLTCOMPONENT_BASE_STOPWATCH();
729   AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
730   int idx=fCurrentInputBlock;
731   if (pObject) {
732     if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
733     } else {
734       HLTError("unknown object %p", pObject);
735     }
736   }
737   if (idx>=0) {
738     if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
739       iSpec=fpInputBlocks[idx].fSpecification;
740     } else {
741       HLTFatal("severe internal error, index out of range");
742     }
743   }
744   return iSpec;
745 }
746
747 int AliHLTComponent::Forward(const TObject* pObject)
748 {
749   // see header file for function documentation
750   int iResult=0;
751   int idx=fCurrentInputBlock;
752   if (pObject) {
753     if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
754     } else {
755       HLTError("unknown object %p", pObject);
756       iResult=-ENOENT;
757     }
758   }
759   if (idx>=0) {
760     fOutputBlocks.push_back(fpInputBlocks[idx]);
761   }
762   return iResult;
763 }
764
765 int AliHLTComponent::Forward(const AliHLTComponentBlockData* pBlock)
766 {
767   // see header file for function documentation
768   int iResult=0;
769   int idx=fCurrentInputBlock;
770   if (pBlock) {
771     if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
772     } else {
773       HLTError("unknown Block %p", pBlock);
774       iResult=-ENOENT;      
775     }
776   }
777   if (idx>=0) {
778     // check for fpInputBlocks pointer done in FindInputBlock
779     fOutputBlocks.push_back(fpInputBlocks[idx]);
780   }
781   return iResult;
782 }
783
784 const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const AliHLTComponentDataType& dt)
785 {
786   // see header file for function documentation
787   ALIHLTCOMPONENT_BASE_STOPWATCH();
788   fSearchDataType=dt;
789   fClassName.clear();
790   int idx=FindInputBlock(fSearchDataType, 0);
791   const AliHLTComponentBlockData* pBlock=NULL;
792   if (idx>=0) {
793     // check for fpInputBlocks pointer done in FindInputBlock
794     pBlock=&fpInputBlocks[idx];
795     fCurrentInputBlock=idx;
796   }
797   return pBlock;
798 }
799
800 const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const char* dtID, 
801                                                                     const char* dtOrigin)
802 {
803   // see header file for function documentation
804   ALIHLTCOMPONENT_BASE_STOPWATCH();
805   AliHLTComponentDataType dt;
806   SetDataType(dt, dtID, dtOrigin);
807   return GetFirstInputBlock(dt);
808 }
809
810 const AliHLTComponentBlockData* AliHLTComponent::GetInputBlock(int index)
811 {
812   // see header file for function documentation
813   ALIHLTCOMPONENT_BASE_STOPWATCH();
814   assert( 0 <= index and index < (int)fCurrentEventData.fBlockCnt );
815   return &fpInputBlocks[index];
816 }
817
818 const AliHLTComponentBlockData* AliHLTComponent::GetNextInputBlock()
819 {
820   // see header file for function documentation
821   ALIHLTCOMPONENT_BASE_STOPWATCH();
822   int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1);
823   const AliHLTComponentBlockData* pBlock=NULL;
824   if (idx>=0) {
825     // check for fpInputBlocks pointer done in FindInputBlock
826     pBlock=&fpInputBlocks[idx];
827     fCurrentInputBlock=idx;
828   }
829   return pBlock;
830 }
831
832 int AliHLTComponent::FindInputBlock(const AliHLTComponentBlockData* pBlock) const
833 {
834   // see header file for function documentation
835   int iResult=-ENOENT;
836   if (fpInputBlocks!=NULL) {
837     if (pBlock) {
838       if (pBlock>=fpInputBlocks && pBlock<fpInputBlocks+fCurrentEventData.fBlockCnt) {
839         iResult=(int)(pBlock-fpInputBlocks);
840       }
841     } else {
842       iResult=-EINVAL;
843     }
844   }
845   return iResult;
846 }
847
848 AliHLTUInt32_t AliHLTComponent::GetSpecification(const AliHLTComponentBlockData* pBlock)
849 {
850   // see header file for function documentation
851   ALIHLTCOMPONENT_BASE_STOPWATCH();
852   AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
853   int idx=fCurrentInputBlock;
854   if (pBlock) {
855     if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
856     } else {
857       HLTError("unknown Block %p", pBlock);
858     }
859   }
860   if (idx>=0) {
861     // check for fpInputBlocks pointer done in FindInputBlock
862     iSpec=fpInputBlocks[idx].fSpecification;
863   }
864   return iSpec;
865 }
866
867 int AliHLTComponent::PushBack(TObject* pObject, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec, 
868                               void* pHeader, int headerSize)
869 {
870   // see header file for function documentation
871   ALIHLTCOMPONENT_BASE_STOPWATCH();
872   int iResult=0;
873   if (pObject) {
874     AliHLTMessage msg(kMESS_OBJECT);
875     msg.WriteObject(pObject);
876     Int_t iMsgLength=msg.Length();
877     if (iMsgLength>0) {
878       msg.SetLength(); // sets the length to the first (reserved) word
879       iResult=InsertOutputBlock(msg.Buffer(), iMsgLength, dt, spec, pHeader, headerSize);
880       if (iResult>=0) {
881         HLTDebug("object %s (%p) size %d inserted to output", pObject->ClassName(), pObject, iMsgLength);
882       }
883     } else {
884       HLTError("object serialization failed for object %p", pObject);
885       iResult=-ENOMSG;
886     }
887   } else {
888     iResult=-EINVAL;
889   }
890   return iResult;
891 }
892
893 int AliHLTComponent::PushBack(TObject* pObject, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
894                               void* pHeader, int headerSize)
895 {
896   // see header file for function documentation
897   ALIHLTCOMPONENT_BASE_STOPWATCH();
898   AliHLTComponentDataType dt;
899   SetDataType(dt, dtID, dtOrigin);
900   return PushBack(pObject, dt, spec, pHeader, headerSize);
901 }
902
903 int AliHLTComponent::PushBack(void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
904                               void* pHeader, int headerSize)
905 {
906   // see header file for function documentation
907   ALIHLTCOMPONENT_BASE_STOPWATCH();
908   return InsertOutputBlock(pBuffer, iSize, dt, spec, pHeader, headerSize);
909 }
910
911 int AliHLTComponent::PushBack(void* pBuffer, int iSize, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
912                               void* pHeader, int headerSize)
913 {
914   // see header file for function documentation
915   ALIHLTCOMPONENT_BASE_STOPWATCH();
916   AliHLTComponentDataType dt;
917   SetDataType(dt, dtID, dtOrigin);
918   return PushBack(pBuffer, iSize, dt, spec, pHeader, headerSize);
919 }
920
921 int AliHLTComponent::InsertOutputBlock(void* pBuffer, int iBufferSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
922                               void* pHeader, int iHeaderSize)
923 {
924   // see header file for function documentation
925   int iResult=0;
926   int iBlkSize = iBufferSize + iHeaderSize;
927   if (pBuffer) {
928     if (fpOutputBuffer && iBlkSize<=(int)(fOutputBufferSize-fOutputBufferFilled)) {
929       AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
930       AliHLTComponentBlockData bd;
931       FillBlockData( bd );
932       bd.fOffset        = fOutputBufferFilled;
933       bd.fSize          = iBlkSize;
934       bd.fDataType      = dt;
935       bd.fSpecification = spec;
936       if (pHeader!=NULL && pHeader!=pTgt) {
937         memcpy(pTgt, pHeader, iHeaderSize);
938       }
939
940       pTgt += (AliHLTUInt8_t) iHeaderSize;
941
942       if (pBuffer!=NULL && pBuffer!=pTgt) {
943         memcpy(pTgt, pBuffer, iBufferSize);
944         
945         //AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer); 
946         //HLTDebug("copy %d bytes from %p to output buffer %p, first word %#x", iBufferSize, pBuffer, pTgt, firstWord);
947       }
948       fOutputBufferFilled+=bd.fSize;
949       fOutputBlocks.push_back( bd );
950       //HLTDebug("buffer inserted to output: size %d data type %s spec %#x", iBlkSize, DataType2Text(dt).c_str(), spec);
951     } else {
952       if (fpOutputBuffer) {
953         HLTError("too little space in output buffer: %d, required %d", fOutputBufferSize-fOutputBufferFilled, iBlkSize);
954       } else {
955         HLTError("output buffer not available");
956       }
957       iResult=-ENOSPC;
958     }
959   } else {
960     iResult=-EINVAL;
961   }
962   return iResult;
963 }
964
965 int AliHLTComponent::EstimateObjectSize(TObject* pObject) const
966 {
967   // see header file for function documentation
968   if (!pObject) return -EINVAL;
969     AliHLTMessage msg(kMESS_OBJECT);
970     msg.WriteObject(pObject);
971     return msg.Length();  
972 }
973
974 AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity, const char* dtID,
975                                                     const char* dtOrigin,
976                                                     AliHLTUInt32_t spec)
977 {
978   // see header file for function documentation
979   ALIHLTCOMPONENT_BASE_STOPWATCH();
980   AliHLTComponentDataType dt;
981   SetDataType(dt, dtID, dtOrigin);
982   return CreateMemoryFile(capacity, dt, spec);
983 }
984
985 AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity,
986                                                     const AliHLTComponentDataType& dt,
987                                                     AliHLTUInt32_t spec)
988 {
989   // see header file for function documentation
990   ALIHLTCOMPONENT_BASE_STOPWATCH();
991   AliHLTMemoryFile* pFile=NULL;
992   if (capacity>=0 && static_cast<unsigned int>(capacity)<=fOutputBufferSize-fOutputBufferFilled){
993     AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
994     pFile=new AliHLTMemoryFile((char*)pTgt, capacity);
995     if (pFile) {
996       unsigned int nofBlocks=fOutputBlocks.size();
997       if (nofBlocks+1>fMemFiles.size()) {
998         fMemFiles.resize(nofBlocks+1, NULL);
999       }
1000       if (nofBlocks<fMemFiles.size()) {
1001         fMemFiles[nofBlocks]=pFile;
1002         AliHLTComponentBlockData bd;
1003         FillBlockData( bd );
1004         bd.fOffset        = fOutputBufferFilled;
1005         bd.fSize          = capacity;
1006         bd.fDataType      = dt;
1007         bd.fSpecification = spec;
1008         fOutputBufferFilled+=bd.fSize;
1009         fOutputBlocks.push_back( bd );
1010       } else {
1011         HLTError("can not allocate/grow object array");
1012         pFile->CloseMemoryFile(0);
1013         delete pFile;
1014         pFile=NULL;
1015       }
1016     }
1017   } else {
1018     HLTError("can not create memory file of size %d (%d available)", capacity, fOutputBufferSize-fOutputBufferFilled);
1019   }
1020   return pFile;
1021 }
1022
1023 AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const char* dtID,
1024                                                     const char* dtOrigin,
1025                                                     AliHLTUInt32_t spec,
1026                                                     float capacity)
1027 {
1028   // see header file for function documentation
1029   ALIHLTCOMPONENT_BASE_STOPWATCH();
1030   AliHLTComponentDataType dt;
1031   SetDataType(dt, dtID, dtOrigin);
1032   int size=fOutputBufferSize-fOutputBufferFilled;
1033   if (capacity<0 || capacity>1.0) {
1034     HLTError("invalid parameter: capacity %f", capacity);
1035     return NULL;
1036   }
1037   size=(int)(size*capacity);
1038   return CreateMemoryFile(size, dt, spec);
1039 }
1040
1041 AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const AliHLTComponentDataType& dt,
1042                                                     AliHLTUInt32_t spec,
1043                                                     float capacity)
1044 {
1045   // see header file for function documentation
1046   ALIHLTCOMPONENT_BASE_STOPWATCH();
1047   int size=fOutputBufferSize-fOutputBufferFilled;
1048   if (capacity<0 || capacity>1.0) {
1049     HLTError("invalid parameter: capacity %f", capacity);
1050     return NULL;
1051   }
1052   size=(int)(size*capacity);
1053   return CreateMemoryFile(size, dt, spec);
1054 }
1055
1056 int AliHLTComponent::Write(AliHLTMemoryFile* pFile, const TObject* pObject,
1057                            const char* key, int option)
1058 {
1059   // see header file for function documentation
1060   int iResult=0;
1061   if (pFile && pObject) {
1062     pFile->cd();
1063     iResult=pObject->Write(key, option);
1064     if (iResult>0) {
1065       // success
1066     } else {
1067       iResult=-pFile->GetErrno();
1068       if (iResult==-ENOSPC) {
1069         HLTError("error writing memory file, buffer too small");
1070       }
1071     }
1072   } else {
1073     iResult=-EINVAL;
1074   }
1075   return iResult;
1076 }
1077
1078 int AliHLTComponent::CloseMemoryFile(AliHLTMemoryFile* pFile)
1079 {
1080   // see header file for function documentation
1081   int iResult=0;
1082   if (pFile) {
1083     AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
1084     int i=0;
1085     while (element!=fMemFiles.end() && iResult>=0) {
1086       if (*element && *element==pFile) {
1087         iResult=pFile->CloseMemoryFile();
1088         
1089         // sync memory files and descriptors
1090         if (iResult>=0) {
1091           fOutputBlocks[i].fSize=(*element)->GetSize()+(*element)->GetHeaderSize();
1092         }
1093         delete *element;
1094         *element=NULL;
1095         return iResult;
1096       }
1097       element++; i++;
1098     }
1099     HLTError("can not find memory file %p", pFile);
1100     iResult=-ENOENT;
1101   } else {
1102     iResult=-EINVAL;
1103   }
1104   return iResult;
1105 }
1106
1107 int AliHLTComponent::CreateEventDoneData(AliHLTComponentEventDoneData /*edd*/)
1108 {
1109   // see header file for function documentation
1110   int iResult=-ENOSYS;
1111   //#warning  function not yet implemented
1112   HLTWarning("function not yet implemented");
1113   return iResult;
1114 }
1115
1116 int AliHLTComponent::ProcessEvent( const AliHLTComponentEventData& evtData,
1117                                    const AliHLTComponentBlockData* blocks, 
1118                                    AliHLTComponentTriggerData& trigData,
1119                                    AliHLTUInt8_t* outputPtr, 
1120                                    AliHLTUInt32_t& size,
1121                                    AliHLTUInt32_t& outputBlockCnt, 
1122                                    AliHLTComponentBlockData*& outputBlocks,
1123                                    AliHLTComponentEventDoneData*& edd )
1124 {
1125   // see header file for function documentation
1126   HLTLogKeyword(GetComponentID());
1127   ALIHLTCOMPONENT_BASE_STOPWATCH();
1128   int iResult=0;
1129   fCurrentEvent=evtData.fEventID;
1130   fCurrentEventData=evtData;
1131   fpInputBlocks=blocks;
1132   fCurrentInputBlock=-1;
1133   fSearchDataType=kAliHLTAnyDataType;
1134   fpOutputBuffer=outputPtr;
1135   fOutputBufferSize=size;
1136   fOutputBufferFilled=0;
1137   fOutputBlocks.clear();
1138
1139   bool bSkipDataProcessing=false;
1140   // find special events
1141   if (fpInputBlocks) {
1142     // first look for all special events and execute in the appropriate
1143     // sequence afterwords
1144     AliHLTUInt32_t eventType=gkAliEventTypeUnknown;
1145     int indexComConfEvent=-1;
1146     int indexUpdtDCSEvent=-1;
1147     int indexSOREvent=-1;
1148     int indexEOREvent=-1;
1149     for (unsigned int i=0; i<evtData.fBlockCnt && iResult>=0; i++) {
1150       if (fpInputBlocks[i].fDataType==kAliHLTDataTypeSOR) {
1151         indexSOREvent=i;
1152       } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEOR) {
1153         indexEOREvent=i;
1154       } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeDDL) {
1155         // DDL list
1156         // this event is most likely deprecated
1157       } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComConf) {
1158         indexComConfEvent=i;
1159       } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeUpdtDCS) {
1160         indexUpdtDCSEvent=i;
1161       } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEvent) {
1162         eventType=fpInputBlocks[i].fSpecification;
1163         bSkipDataProcessing|=(fpInputBlocks[i].fSpecification==gkAliEventTypeConfiguration);
1164         bSkipDataProcessing|=(fpInputBlocks[i].fSpecification==gkAliEventTypeReadPreprocessor);
1165       }
1166     }
1167     if (indexSOREvent>=0) {
1168       // start of run
1169       if (fpRunDesc==NULL) {
1170         fpRunDesc=new AliHLTRunDesc;
1171         if (fpRunDesc) {
1172           if ((iResult=CopyStruct(fpRunDesc, sizeof(AliHLTRunDesc), indexSOREvent, "AliHLTRunDesc", "SOR"))>0) {
1173             HLTDebug("set run decriptor, run no %d", fpRunDesc->fRunNo);
1174             SetCDBRunNo(fpRunDesc->fRunNo);
1175           }
1176         } else {
1177           iResult=-ENOMEM;
1178         }
1179       } else {
1180         HLTWarning("already received SOR event run no %d, ignoring SOR", fpRunDesc->fRunNo);
1181       }
1182     }
1183     if (indexEOREvent>=0) {
1184       if (fpRunDesc!=NULL) {
1185         if (fpRunDesc) {
1186           AliHLTRunDesc rundesc;
1187           if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexEOREvent, "AliHLTRunDesc", "SOR"))>0) {
1188             if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
1189               HLTWarning("run no mismatch: SOR %d, EOR %d", fpRunDesc->fRunNo, rundesc.fRunNo);
1190             } else {
1191               HLTDebug("EOR run no %d", fpRunDesc->fRunNo);
1192             }
1193           }
1194           AliHLTRunDesc* pRunDesc=fpRunDesc;
1195           fpRunDesc=NULL;
1196           delete pRunDesc;
1197         }
1198       } else {
1199         HLTWarning("did not receive SOR, ignoring EOR");
1200       }
1201     }
1202     if (indexComConfEvent>=0 || eventType==gkAliEventTypeConfiguration) {
1203       TString cdbEntry;
1204       if (indexComConfEvent>=0 && fpInputBlocks[indexComConfEvent].fPtr!=NULL && fpInputBlocks[indexComConfEvent].fSize>0) {
1205         cdbEntry.Append(reinterpret_cast<const char*>(fpInputBlocks[indexComConfEvent].fPtr), fpInputBlocks[indexComConfEvent].fSize);
1206       }
1207       HLTDebug("received component configuration command: entry %s", cdbEntry.IsNull()?"none":cdbEntry.Data());
1208       int tmpResult=Reconfigure(cdbEntry[0]==0?NULL:cdbEntry.Data(), fChainId.c_str());
1209       if (tmpResult<0) {
1210         HLTWarning("reconfiguration of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
1211       }
1212     }
1213     if (indexUpdtDCSEvent>=0 || eventType==gkAliEventTypeReadPreprocessor) {
1214       TString modules;
1215       if (fpInputBlocks[indexUpdtDCSEvent].fPtr!=NULL && fpInputBlocks[indexUpdtDCSEvent].fSize>0) {
1216         modules.Append(reinterpret_cast<const char*>(fpInputBlocks[indexUpdtDCSEvent].fPtr), fpInputBlocks[indexUpdtDCSEvent].fSize);
1217       }
1218       HLTDebug("received preprocessor update command: detectors %s", modules.IsNull()?"ALL":modules.Data());
1219       int tmpResult=ReadPreprocessorValues(modules[0]==0?"ALL":modules.Data());
1220       if (tmpResult<0) {
1221         HLTWarning("preprocessor update of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
1222       }
1223     }
1224   }
1225   
1226   AliHLTComponentBlockDataList blockData;
1227   { // dont delete, sets the scope for the stopwatch guard
1228     ALIHLTCOMPONENT_DA_STOPWATCH();
1229     iResult=DoProcessing(evtData, blocks, trigData, outputPtr, size, blockData, edd);
1230   } // end of the scope of the stopwatch guard
1231   if (iResult>=0 && !bSkipDataProcessing) {
1232     if (fOutputBlocks.size()>0) {
1233       //HLTDebug("got %d block(s) via high level interface", fOutputBlocks.size());
1234       
1235       // sync memory files and descriptors
1236       AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
1237       int i=0;
1238       while (element!=fMemFiles.end() && iResult>=0) {
1239         if (*element) {
1240           if ((*element)->IsClosed()==0) {
1241             HLTWarning("memory file has not been closed, force flush");
1242             iResult=CloseMemoryFile(*element);
1243           }
1244         }
1245         element++; i++;
1246       }
1247
1248       if (iResult>=0) {
1249         // create the descriptor list
1250         if (blockData.size()>0) {
1251           HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks");
1252           iResult=-EFAULT;
1253         } else {
1254           iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks);
1255           size=fOutputBufferFilled;
1256         }
1257       }
1258     } else {
1259       iResult=MakeOutputDataBlockList(blockData, &outputBlockCnt, &outputBlocks);
1260     }
1261     if (iResult<0) {
1262       HLTFatal("component %s (%p): can not convert output block descriptor list", GetComponentID(), this);
1263     }
1264   }
1265   if (iResult<0 || bSkipDataProcessing) {
1266     outputBlockCnt=0;
1267     outputBlocks=NULL;
1268   }
1269   CleanupInputObjects();
1270   if (iResult>=0 && !bSkipDataProcessing) {
1271     IncrementEventCounter();
1272   }
1273   return iResult;
1274 }
1275
1276 AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard()
1277   :
1278   fpStopwatch(NULL),
1279   fpPrec(NULL)
1280 {
1281   // standard constructor (not for use)
1282 }
1283
1284 AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(TStopwatch* pStopwatch)
1285   :
1286   fpStopwatch(pStopwatch),
1287   fpPrec(NULL)
1288 {
1289   // constructor
1290
1291   // check for already existing guard
1292   if (fgpCurrent) fpPrec=fgpCurrent;
1293   fgpCurrent=this;
1294
1295   // stop the preceeding guard if it controls a different stopwatch
1296   int bStart=1;
1297   if (fpPrec && fpPrec!=this) bStart=fpPrec->Hold(fpStopwatch);
1298
1299   // start the stopwatch if the current guard controls a different one
1300   if (fpStopwatch && bStart==1) fpStopwatch->Start(kFALSE);
1301 }
1302
1303 AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(const AliHLTStopwatchGuard&)
1304   :
1305   fpStopwatch(NULL),
1306   fpPrec(NULL)
1307 {
1308   //
1309   // copy constructor not for use
1310   //
1311 }
1312
1313 AliHLTComponent::AliHLTStopwatchGuard& AliHLTComponent::AliHLTStopwatchGuard::operator=(const AliHLTStopwatchGuard&)
1314 {
1315   //
1316   // assignment operator not for use
1317   //
1318   fpStopwatch=NULL;
1319   fpPrec=NULL;
1320   return *this;
1321 }
1322
1323 AliHLTComponent::AliHLTStopwatchGuard* AliHLTComponent::AliHLTStopwatchGuard::fgpCurrent=NULL;
1324
1325 AliHLTComponent::AliHLTStopwatchGuard::~AliHLTStopwatchGuard()
1326 {
1327   // destructor
1328
1329   // resume the preceeding guard if it controls a different stopwatch
1330   int bStop=1;
1331   if (fpPrec && fpPrec!=this) bStop=fpPrec->Resume(fpStopwatch);
1332
1333   // stop the stopwatch if the current guard controls a different one
1334   if (fpStopwatch && bStop==1) fpStopwatch->Stop();
1335
1336   // resume to the preceeding guard
1337   fgpCurrent=fpPrec;
1338 }
1339
1340 int AliHLTComponent::AliHLTStopwatchGuard::Hold(TStopwatch* pSucc)
1341 {
1342   // see header file for function documentation
1343   if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Stop();
1344   return fpStopwatch!=pSucc?1:0;
1345 }
1346
1347 int AliHLTComponent::AliHLTStopwatchGuard::Resume(TStopwatch* pSucc)
1348 {
1349   // see header file for function documentation
1350   if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Start(kFALSE);
1351   return fpStopwatch!=pSucc?1:0;
1352 }
1353
1354 int AliHLTComponent::SetStopwatch(TObject* pSW, AliHLTStopwatchType type) 
1355 {
1356   // see header file for function documentation
1357   int iResult=0;
1358   if (pSW!=NULL && type<kSWTypeCount) {
1359     if (fpStopwatches) {
1360       TObject* pObj=fpStopwatches->At((int)type);
1361       if (pSW==NULL        // explicit reset
1362           || pObj==NULL) { // explicit set
1363         fpStopwatches->AddAt(pSW, (int)type);
1364       } else if (pObj!=pSW) {
1365         HLTWarning("stopwatch %d already set, reset first", (int)type);
1366         iResult=-EBUSY;
1367       }
1368     }
1369   } else {
1370     iResult=-EINVAL;
1371   }
1372   return iResult;
1373 }
1374
1375 int AliHLTComponent::SetStopwatches(TObjArray* pStopwatches)
1376 {
1377   // see header file for function documentation
1378   if (pStopwatches==NULL) return -EINVAL;
1379
1380   int iResult=0;
1381   for (int i=0 ; i<(int)kSWTypeCount && pStopwatches->GetEntries(); i++)
1382     SetStopwatch(pStopwatches->At(i), (AliHLTStopwatchType)i);
1383   return iResult;
1384 }
1385
1386 AliHLTUInt32_t AliHLTComponent::GetRunNo() const
1387 {
1388   // see header file for function documentation
1389   if (fpRunDesc==NULL) return 0;
1390   return fpRunDesc->fRunNo;
1391 }
1392
1393 AliHLTUInt32_t AliHLTComponent::GetRunType() const
1394 {
1395   // see header file for function documentation
1396   if (fpRunDesc==NULL) return 0;
1397   return fpRunDesc->fRunType;
1398 }
1399
1400 int AliHLTComponent::CopyStruct(void* pStruct, unsigned int iStructSize, unsigned int iBlockNo,
1401                                 const char* structname, const char* eventname)
1402 {
1403   // see header file for function documentation
1404   int iResult=0;
1405   if (pStruct!=NULL && iStructSize>sizeof(AliHLTUInt32_t)) {
1406     if (fpInputBlocks!=NULL && iBlockNo<fCurrentEventData.fBlockCnt) {
1407       AliHLTUInt32_t* pTgt=(AliHLTUInt32_t*)pStruct;
1408       if (fpInputBlocks[iBlockNo].fPtr && fpInputBlocks[iBlockNo].fSize) {
1409         AliHLTUInt32_t copy=*((AliHLTUInt32_t*)fpInputBlocks[iBlockNo].fPtr);
1410         if (fpInputBlocks[iBlockNo].fSize!=copy) {
1411           HLTWarning("%s event: mismatch of block size (%d) and structure size (%d)", eventname, fpInputBlocks[iBlockNo].fSize, copy);
1412           if (copy>fpInputBlocks[iBlockNo].fSize) copy=fpInputBlocks[iBlockNo].fSize;
1413         }
1414         if (copy!=iStructSize) {
1415           HLTWarning("%s event: mismatch in %s version (data type version %d)", eventname, structname, ALIHLT_DATA_TYPES_VERSION);
1416           if (copy>iStructSize) {
1417             copy=iStructSize;
1418           } else {
1419             memset(pTgt, 0, iStructSize);
1420           }
1421         }
1422         memcpy(pTgt, fpInputBlocks[iBlockNo].fPtr, copy);
1423         *pTgt=iStructSize;
1424         iResult=copy;
1425       } else {
1426         HLTWarning("%s event: missing data block", eventname);
1427       }
1428     } else {
1429       iResult=-ENODATA;
1430     }
1431   } else {
1432     HLTError("invalid struct");
1433     iResult=-EINVAL;
1434   }
1435   return iResult;
1436 }
1437
1438 void AliHLTComponent::SetDDLBit(AliHLTEventDDL &list, Int_t ddlId, Bool_t state ) const
1439 {
1440   // see header file for function documentation
1441   
1442   // -- Detector offset
1443   Int_t ddlIdBase =  TMath::FloorNint( (Double_t) ddlId / 256.0 );
1444   
1445   // -- Word Base = 1. word of detector ( TPC has 8 words, TOF 3 ) 
1446   Int_t wordBase = 0;
1447
1448   if ( ddlIdBase <= 3 )
1449     wordBase = ddlIdBase;
1450   else if ( ddlIdBase > 3 && ddlIdBase < 5 )
1451     wordBase = ddlIdBase + 7;
1452   else 
1453     wordBase = ddlIdBase + 9;
1454
1455   // -- Bit index in Word
1456   Int_t bitIdx = ddlId % 32;
1457
1458   // -- Index of word
1459   Int_t wordIdx = wordBase;
1460
1461   // -- if TPC (3) or TOD (5) add word idx
1462   if ( ( ddlIdBase == 3 ) || ( ddlIdBase == 5 ) ) {
1463     wordIdx += TMath::FloorNint( (Double_t) ( ddlId - ( ddlIdBase * 256 ) ) / 32.0 );
1464   }
1465
1466   // -- Set -- 'OR' word with bit mask;
1467   if ( state )
1468     list.fList[wordIdx] |= ( 0x00000001 << bitIdx );
1469   // -- Unset -- 'AND' word with bit mask;
1470   else
1471     list.fList[wordIdx] &= ( 0xFFFFFFFF ^ ( 0x00000001 << bitIdx ) );
1472 }
1473
1474 Int_t AliHLTComponent::GetFirstUsedDDLWord(AliHLTEventDDL &list) const
1475 {
1476   // see header file for function documentation
1477
1478   Int_t iResult = -1;
1479
1480   for ( Int_t wordNdx = 0 ; wordNdx < gkAliHLTDDLListSize ; wordNdx++ ) {
1481
1482     if ( list.fList[wordNdx] != 0 && iResult == -1 ) {
1483       // check for special cases TPC and TOF
1484       if ( wordNdx > 3 && wordNdx <= 10 ) {
1485         wordNdx = 10;
1486         iResult = 3;
1487       }
1488       else if ( wordNdx > 12 && wordNdx <= 14 ) {
1489         wordNdx = 14;
1490         iResult = 12;
1491       }
1492       else
1493         iResult = wordNdx;
1494     }
1495     else if ( list.fList[wordNdx] != 0 && iResult >= 0 ) {
1496       HLTError( "DDLIDs for minimum of TWO detectors ( %d, %d ) set, this function works only for ONE detector.", iResult, wordNdx );
1497       iResult = -1;
1498       break;
1499     }
1500   }
1501
1502   return iResult;
1503 }