]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTTask.cxx
Removing unuseful print and putting some important one
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTTask.cxx
1 // $Id$
2 // splitted from AliHLTConfiguration.cxx,v 1.25 2007/10/12 13:24:47
3 /**************************************************************************
4  * This file is property of and copyright by the ALICE HLT Project        * 
5  * ALICE Experiment at CERN, All rights reserved.                         *
6  *                                                                        *
7  * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
8  *                  for The ALICE HLT Project.                            *
9  *                                                                        *
10  * Permission to use, copy, modify and distribute this software and its   *
11  * documentation strictly for non-commercial purposes is hereby granted   *
12  * without fee, provided that the above copyright notice appears in all   *
13  * copies and that both the copyright notice and this permission notice   *
14  * appear in the supporting documentation. The authors make no claims     *
15  * about the suitability of this software for any purpose. It is          *
16  * provided "as is" without express or implied warranty.                  *
17  **************************************************************************/
18
19 /** @file   AliHLTTask.cxx
20     @author Matthias Richter
21     @date   
22     @brief  Implementation of HLT tasks.
23 */
24
25 // see header file for class documentation
26 // or
27 // refer to README to build package
28 // or
29 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
30
31 #if __GNUC__>= 3
32 using namespace std;
33 #endif
34
35 #include <cerrno>
36 #include <cassert>
37 #include <iostream>
38 #include <string>
39 #include <ctime>
40 #include "AliHLTTask.h"
41 #include "AliHLTConfiguration.h"
42 #include "AliHLTComponent.h"
43 #include "AliHLTComponentHandler.h"
44 #include "TList.h"
45
46 /** ROOT macro for the implementation of ROOT specific class methods */
47 ClassImp(AliHLTTask)
48
49 AliHLTTask::AliHLTTask()
50   :
51   fpConfiguration(NULL),
52   fpComponent(NULL),
53   fpDataBuffer(NULL),
54   fListTargets(),
55   fListDependencies(),
56   fBlockDataArray()
57 {
58   // see header file for class documentation
59   // or
60   // refer to README to build package
61   // or
62   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
63 }
64
65 AliHLTTask::AliHLTTask(AliHLTConfiguration* pConf)
66   :
67   fpConfiguration(pConf),
68   fpComponent(NULL),
69   fpDataBuffer(NULL),
70   fListTargets(),
71   fListDependencies(),
72   fBlockDataArray()
73 {
74   // see header file for function documentation
75 }
76
77 AliHLTTask::~AliHLTTask()
78 {
79   // see header file for function documentation
80   TObjLink* lnk=fListDependencies.FirstLink();
81
82   while (lnk!=NULL) {
83     AliHLTTask* pTask=(AliHLTTask*)lnk->GetObject();
84     pTask->UnsetTarget(this);
85     lnk=lnk->Next();
86   }
87   lnk=fListTargets.FirstLink();
88
89   while (lnk!=NULL) {
90     AliHLTTask* pTask=(AliHLTTask*)lnk->GetObject();
91     pTask->UnsetDependency(this);
92     lnk=lnk->Next();
93   }
94
95   if (fpComponent) delete fpComponent;
96   fpComponent=NULL;
97 }
98
99 int AliHLTTask::Init(AliHLTConfiguration* pConf, AliHLTComponentHandler* pCH)
100 {
101   // see header file for function documentation
102   int iResult=0;
103   if (fpConfiguration!=NULL && pConf!=NULL && fpConfiguration!=pConf) {
104     HLTWarning("overriding existing reference to configuration object %p by %p",
105                fpConfiguration, pConf);
106   }
107   if (pConf!=NULL) fpConfiguration=pConf;
108   iResult=CreateComponent(fpConfiguration, pCH, fpComponent);
109   if (iResult>=0) {
110     iResult=CustomInit(pCH);
111   }
112   return iResult;
113 }
114
115 int AliHLTTask::CreateComponent(AliHLTConfiguration* pConf, AliHLTComponentHandler* pCH, AliHLTComponent*& pComponent) const
116 {
117   // see header file for class documentation
118   int iResult=0;
119   if (pConf) {
120     if (pCH) {
121       int argc=0;
122       const char** argv=NULL;
123       if ((iResult=pConf->GetArguments(&argv))>=0) {
124         argc=iResult; // just to make it clear
125         // TODO: we have to think about the optional environment parameter,
126         // currently just set to NULL.
127         iResult=pCH->CreateComponent(pConf->GetComponentID(), pComponent);
128         if (pComponent && iResult>=0) {
129           TString description;
130           description.Form("chainid=%s", GetName());
131           pComponent->SetComponentDescription(description.Data());
132           const AliHLTAnalysisEnvironment* pEnv=pCH->GetEnvironment();
133           if ((iResult=pComponent->Init(pEnv, NULL, argc, argv))>=0) {
134             //HLTDebug("component %s (%p) created", pComponent->GetComponentID(), pComponent); 
135           } else {
136             HLTError("Initialization of component \"%s\" failed with error %d", pComponent->GetComponentID(), iResult);
137           }
138         } else {
139           //HLTError("can not find component \"%s\" (%d)", pConf->GetComponentID(), iResult);
140         }
141       } else {
142         HLTError("can not get argument list for configuration %s (%s)", pConf->GetName(), pConf->GetComponentID());
143         iResult=-EINVAL;
144       }
145     } else {
146       HLTError("component handler instance needed for task initialization");
147       iResult=-EINVAL;
148     }
149   } else {
150     HLTError("configuration object instance needed for task initialization");
151     iResult=-EINVAL;
152   }
153   return iResult;
154 }
155
156 int AliHLTTask::Deinit()
157 {
158   // see header file for function documentation
159   int iResult=0;
160   CustomCleanup();
161   AliHLTComponent* pComponent=GetComponent();
162   fpComponent=NULL;
163   if (pComponent) {
164     //HLTDebug("delete component %s (%p)", pComponent->GetComponentID(), pComponent); 
165     pComponent->Deinit();
166     delete pComponent;
167   } else {
168     HLTWarning("task doesn't seem to be in initialized");
169   }
170   return iResult;
171 }
172
173 const char *AliHLTTask::GetName() const
174 {
175   // see header file for function documentation
176   if (fpConfiguration)
177     return fpConfiguration->GetName();
178   return TObject::GetName();
179 }
180
181 AliHLTConfiguration* AliHLTTask::GetConf() const
182 {
183   // see header file for function documentation
184   return fpConfiguration;
185 }
186
187 AliHLTComponent* AliHLTTask::GetComponent() const
188 {
189   // see header file for function documentation
190   return fpComponent;
191 }
192
193 AliHLTTask* AliHLTTask::FindDependency(const char* id)
194 {
195   // see header file for function documentation
196   AliHLTTask* pTask=NULL;
197   if (id) {
198     pTask=(AliHLTTask*)fListDependencies.FindObject(id);
199   }
200   return pTask;
201 }
202
203 int AliHLTTask::FollowDependency(const char* id, TList* pTgtList)
204 {
205   // see header file for function documentation
206   int iResult=0;
207   if (id) {
208     AliHLTTask* pDep=NULL;
209     if ((pDep=(AliHLTTask*)fListDependencies.FindObject(id))!=NULL) {
210       if (pTgtList) pTgtList->Add(pDep);
211       iResult++;
212     } else {
213       TObjLink* lnk=fListDependencies.FirstLink();
214       while (lnk && iResult==0) {
215         pDep=(AliHLTTask*)lnk->GetObject();
216         if (pDep) {
217           if ((iResult=pDep->FollowDependency(id, pTgtList))>0) {
218             if (pTgtList) pTgtList->AddFirst(pDep);
219             iResult++;
220           }
221         } else {
222           iResult=-EFAULT;
223         }
224         lnk=lnk->Next();
225       }
226     }
227   } else {
228     iResult=-EINVAL;
229   }
230   return iResult;
231 }
232
233 void AliHLTTask::PrintDependencyTree(const char* id, int bFromConfiguration)
234 {
235   // see header file for function documentation
236   HLTLogKeyword("task dependencies");
237   int iResult=0;
238   TList tgtList;
239   if (bFromConfiguration) {
240     if (fpConfiguration)
241       iResult=fpConfiguration->FollowDependency(id, &tgtList);
242     else
243       iResult=-EFAULT;
244   } else
245     iResult=FollowDependency(id, &tgtList);
246   if (iResult>0) {
247     HLTMessage("     dependency level %d ", iResult);
248     TObjLink* lnk=tgtList.FirstLink();
249     int i=iResult;
250     char* pSpace = new char[iResult+1];
251     if (pSpace) {
252       memset(pSpace, 32, iResult);
253       pSpace[i]=0;
254       while (lnk) {
255         TObject* obj=lnk->GetObject();
256         HLTMessage("     %s^-- %s ", &pSpace[i--], obj->GetName());
257         lnk=lnk->Next();
258       }
259       delete [] pSpace;
260     } else {
261       iResult=-ENOMEM;
262     }
263   }
264 }
265
266 int AliHLTTask::SetDependency(AliHLTTask* pDep)
267 {
268   // see header file for function documentation
269   int iResult=0;
270   if (pDep) {
271     if (FindDependency(pDep->GetName())==NULL) {
272       fListDependencies.Add(pDep);
273     } else {
274       iResult=-EEXIST;
275     }
276   } else {
277     iResult=-EINVAL;
278   }
279   return iResult;
280 }
281
282 int AliHLTTask::UnsetDependency(AliHLTTask* pDep)
283 {
284   // see header file for function documentation
285   fListDependencies.Remove(pDep);
286   if (fpConfiguration) {
287     fpConfiguration->InvalidateSources();
288   }
289   return 0;
290 }
291
292 int AliHLTTask::CheckDependencies()
293 {
294   // see header file for function documentation
295   int iResult=0;
296   AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
297   while (pSrc) {
298     if (FindDependency(pSrc->GetName())==NULL) {
299       //HLTDebug("dependency \"%s\" unresolved", pSrc->GetName());
300       iResult++;
301     }
302     pSrc=fpConfiguration->GetNextSource();
303   }
304   return iResult;
305 }
306
307
308 int AliHLTTask::Depends(AliHLTTask* pTask)
309 {
310   // see header file for function documentation
311   int iResult=0;
312   if (pTask) {
313     if (fpConfiguration) {
314       iResult=fpConfiguration->GetSource(pTask->GetName())!=NULL;
315       if (iResult>0) {
316         //HLTDebug("task  \"%s\" depends on \"%s\"", GetName(), pTask->GetName());
317       } else {
318         //HLTDebug("task  \"%s\" independend of \"%s\"", GetName(), pTask->GetName());
319       }
320     } else {
321       iResult=-EFAULT;
322     }
323   } else {
324     iResult=-EINVAL;
325   }
326   return iResult;
327 }
328
329 AliHLTTask* AliHLTTask::FindTarget(const char* id)
330 {
331   // see header file for function documentation
332   AliHLTTask* pTask=NULL;
333   if (id) {
334     pTask=(AliHLTTask*)fListTargets.FindObject(id);
335   }
336   return pTask;
337 }
338
339 int AliHLTTask::SetTarget(AliHLTTask* pTgt)
340 {
341   // see header file for function documentation
342   int iResult=0;
343   if (pTgt) {
344     if (FindTarget(pTgt->GetName())==NULL) {
345       fListTargets.Add(pTgt);
346     } else {
347       iResult=-EEXIST;
348     }
349   } else {
350     iResult=-EINVAL;
351   }
352   return iResult;
353 }
354
355 int AliHLTTask::UnsetTarget(AliHLTTask* pTarget)
356 {
357   // see header file for function documentation
358   fListTargets.Remove(pTarget);
359   return 0;
360 }
361
362 int AliHLTTask::StartRun()
363 {
364   // see header file for function documentation
365   int iResult=0;
366   int iNofInputDataBlocks=0;
367   AliHLTComponent* pComponent=GetComponent();
368   if (pComponent) {
369     // determine the number of input data blocks provided from the source tasks
370     { // set scope for lnk as a local variable
371     TObjLink* lnk=fListDependencies.FirstLink();
372     while (lnk && iResult>=0) {
373       AliHLTTask* pSrcTask=(AliHLTTask*)lnk->GetObject();
374       if (pSrcTask) {
375         if ((iResult=pSrcTask->GetNofMatchingDataTypes(this))>0) {
376           iNofInputDataBlocks+=iResult;
377         } else if (iResult==0) {
378           HLTWarning("source task %s (%p) does not provide any matching data type for task %s (%p)", pSrcTask->GetName(), pSrcTask, GetName(), this);
379         } else {
380           HLTError("task %s (%p): error getting matching data types for source task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
381           iResult=-EFAULT;
382         }
383       }
384       lnk=lnk->Next();
385     }
386     }
387     if (iResult>=0) {
388       if (fBlockDataArray.size()>0) {
389         HLTWarning("block data array for task %s (%p) was not cleaned", GetName(), this);
390         fBlockDataArray.clear();
391       }
392
393       // component init
394       // the initialization of the component is done by the ComponentHandler after creation
395       // of the component.
396       //iResult=Init( AliHLTAnalysisEnvironment* environ, void* environ_param, int argc, const char** argv );
397
398       // allocate the data buffer, which controls the output buffer and subscriptions
399       if (iResult>=0) {
400         fpDataBuffer=new AliHLTDataBuffer;
401         if (fpDataBuffer!=NULL) {
402           fpDataBuffer->SetLocalLoggingLevel(GetLocalLoggingLevel());
403           HLTDebug("created data buffer %p for task %s (%p)", fpDataBuffer, GetName(), this);
404           TObjLink* lnk=fListTargets.FirstLink();
405           while (lnk && iResult>=0) {
406             AliHLTTask* pTgtTask=(AliHLTTask*)lnk->GetObject();
407             if (pTgtTask) {
408               if ((iResult=fpDataBuffer->SetConsumer(pTgtTask->GetComponent()))>=0) {
409               }
410             } else {
411               break;
412               iResult=-EFAULT;
413             }
414             lnk=lnk->Next();
415           }
416         } else {
417           HLTFatal("can not create data buffer object, memory allocation failed");
418           iResult=-ENOMEM;
419         }
420       }
421     }
422     if (iResult>=0) {
423       // send the SOR event
424       
425     }
426   } else {
427     HLTError("task %s (%p) does not have a component", GetName(), this);
428     iResult=-EFAULT;
429   }
430   return iResult;
431 }
432
433 int AliHLTTask::EndRun()
434 {
435   // see header file for function documentation
436   int iResult=0;
437   if (fBlockDataArray.size()>0) {
438     fBlockDataArray.clear();
439   }
440   if (fpDataBuffer) {
441     AliHLTDataBuffer* pBuffer=fpDataBuffer;
442     fpDataBuffer=NULL;
443     delete pBuffer;
444   }
445   return iResult;
446 }
447
448 int AliHLTTask::ProcessTask(Int_t eventNo, AliHLTUInt32_t eventType, AliHLTUInt64_t trgMask)
449 {
450   // see header file for function documentation
451   int iResult=0;
452   AliHLTComponent* pComponent=GetComponent();
453   if (pComponent && fpDataBuffer) {
454     HLTDebug("Processing task %s (%p) fpDataBuffer %p", GetName(), this, fpDataBuffer);
455     fpDataBuffer->Reset();
456     int iSourceDataBlock=0;
457     int iInputDataVolume=0;
458
459     AliHLTTask* pSrcTask=NULL;
460     AliHLTTaskPList subscribedTaskList;
461     TObjLink* lnk=fListDependencies.FirstLink();
462
463     // instances of SOR and EOR events to be kept
464     int iSOR=-1;
465     int iEOR=-1;
466     // TODO 2009-09-30
467     // generalize handling of the special blocks to be forwarded on SOR and EOR
468     // just adding a new specific handling for the ECS parameter block as a quick
469     // solution
470     int iECS=-1;
471
472     // subscribe to all source tasks
473     fBlockDataArray.clear();
474     while (lnk && iResult>=0) {
475       pSrcTask=(AliHLTTask*)lnk->GetObject();
476       if (pSrcTask) {
477         int iMatchingDB=pSrcTask->GetNofMatchingDataBlocks(this);
478         if (iMatchingDB<0) {
479           HLTError("task %s (%p): error getting no of matching data blocks from task %s (%p), error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iMatchingDB);
480           iResult=iMatchingDB;
481           break;
482         } else if (iMatchingDB==0) {
483           HLTDebug("source task %s (%p) does not provide any matching data type for task %s (%p)", pSrcTask->GetName(), pSrcTask, GetName(), this);
484         }
485         if ((iResult=pSrcTask->Subscribe(this, fBlockDataArray))>=0) {
486           iSOR=iEOR=iECS=-1;
487           AliHLTComponentBlockDataList::iterator block=fBlockDataArray.begin();
488           for (int i=0; block!=fBlockDataArray.end(); i++) {
489             bool bRemove=0;
490             bRemove|=(*block).fDataType==kAliHLTDataTypeSOR && !(iSOR<0 && (iSOR=i)>=0);
491             bRemove|=(*block).fDataType==kAliHLTDataTypeEOR && !(iEOR<0 && (iEOR=i)>=0);
492             bRemove|=(*block).fDataType==kAliHLTDataTypeECSParam && !(iECS<0 && (iECS=i)>=0);
493             //HLTInfo("block %d, iSOR=%d iEOR=%d remove=%d", i, iSOR, iEOR, bRemove);
494             if (i<iSourceDataBlock) {
495               assert(!bRemove);
496             } else if (bRemove) {
497               HLTDebug("remove duplicated event %s (%d)", AliHLTComponent::DataType2Text((*block).fDataType).c_str(), i);
498               pSrcTask->Release(&(*block), this);
499               block=fBlockDataArray.erase(block);
500               continue;
501             } else {
502             iInputDataVolume+=(*block).fSize;
503             // put the source task as many times into the list as it provides data blocks
504             // makes the bookkeeping for the data release easier
505             subscribedTaskList.push_back(pSrcTask);
506             }
507             block++;
508           }
509           HLTDebug("Task %s (%p) successfully subscribed to %d data block(s) of task %s (%p)", GetName(), this, iResult, pSrcTask->GetName(), pSrcTask);
510           iSourceDataBlock=fBlockDataArray.size();        
511           iResult=0;
512         } else {
513           HLTError("Task %s (%p): subscription to task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iResult);
514           iResult=-EFAULT;
515         }
516       } else {
517         HLTFatal("fatal internal error in ROOT list handling");
518         iResult=-EFAULT;
519       }
520       lnk=lnk->Next();
521     }    
522
523     // process the event
524     int iNofTrial=0; // repeat processing if component returns -ENOSPC
525     AliHLTUInt32_t iLastOutputDataSize=0;
526     if (iResult>=0) {
527     do {
528       long unsigned int iOutputDataSize=0;
529       AliHLTConfiguration* pConf=GetConf();
530       // check if there was a buffer size specified, query output size
531       // estimator from component otherwize
532       if (pConf && pConf->GetOutputBufferSize()>=0) {
533         iOutputDataSize=pConf->GetOutputBufferSize();
534       } else {
535       long unsigned int iConstBase=0;
536       double fInputMultiplier=0;
537       if (pComponent->GetComponentType()!=AliHLTComponent::kSink) {
538         pComponent->GetOutputDataSize(iConstBase, fInputMultiplier);
539         // add a small margin to the buffer to allow optional component
540         // statistics
541         iConstBase+=100;
542 #if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
543         for (AliHLTComponentBlockDataList::iterator element=fBlockDataArray.begin();
544              element!=fBlockDataArray.end(); element++) {
545           if (element->fDataType==kAliHLTDataTypeComponentStatistics) {
546             iConstBase+=element->fSize;
547           }
548         }
549 #endif
550       }
551       if (fInputMultiplier<0) {
552         HLTWarning("ignoring negative input multiplier");
553         fInputMultiplier=0;
554       }
555       iOutputDataSize=int(fInputMultiplier*iInputDataVolume) + iConstBase;
556       //HLTDebug("task %s: reqired output size %d", GetName(), iOutputDataSize);
557       }
558       if (iNofTrial>0) {
559         // dont process again if the buffer size is the same
560         if (iLastOutputDataSize==iOutputDataSize) break;
561         HLTImportant("processing event %d again with buffer size %d", eventNo, iOutputDataSize);
562       }
563       AliHLTUInt8_t* pTgtBuffer=NULL;
564       if (iOutputDataSize>0) pTgtBuffer=fpDataBuffer->GetTargetBuffer(iOutputDataSize);
565       //HLTDebug("provided raw buffer %p", pTgtBuffer);
566       AliHLTComponentEventData evtData;
567       AliHLTComponent::FillEventData(evtData);
568       if (eventNo>=0)
569         evtData.fEventID=(AliHLTEventID_t)eventNo;
570       evtData.fEventCreation_s=static_cast<AliHLTUInt32_t>(time(NULL));
571       AliHLTComponentTriggerData trigData;
572       AliHLTEventTriggerData evtTrigData;
573       trigData.fStructSize=sizeof(trigData);
574       trigData.fDataSize=sizeof(AliHLTEventTriggerData);
575       memset(&evtTrigData, 0, trigData.fDataSize);
576       evtTrigData.fCommonHeaderWordCnt=gkAliHLTCommonHeaderCount;
577       evtTrigData.fCommonHeader[5]=trgMask&0xffffffff;
578       trgMask>>=32;
579       evtTrigData.fCommonHeader[6]=trgMask&0x3ffff;
580       trigData.fData=&evtTrigData;
581       iLastOutputDataSize=iOutputDataSize;
582       AliHLTUInt32_t size=iOutputDataSize;
583       AliHLTUInt32_t outputBlockCnt=0;
584       AliHLTComponentBlockData* outputBlocks=NULL;
585       AliHLTComponentEventDoneData* edd=NULL;
586       if (pTgtBuffer!=NULL || iOutputDataSize==0) {
587         // add event type data block
588         // the block is removed immediately after processing from the list
589         AliHLTComponentBlockData eventTypeBlock;
590         AliHLTComponent::FillBlockData(eventTypeBlock);
591         // Note: no payload!
592         eventTypeBlock.fDataType=kAliHLTDataTypeEvent;
593         eventTypeBlock.fSpecification=eventType;
594         fBlockDataArray.push_back(eventTypeBlock);
595
596         // process
597         evtData.fBlockCnt=fBlockDataArray.size();
598         iResult=pComponent->ProcessEvent(evtData, &fBlockDataArray[0], trigData, pTgtBuffer, size, outputBlockCnt, outputBlocks, edd);
599         HLTDebug("component %s ProcessEvent finnished (%d): size=%d blocks=%d", pComponent->GetComponentID(), iResult, size, outputBlockCnt);
600
601         // EventDoneData is for the moment ignored in AliHLTSystem
602         if (edd) {
603           HLTDebug("got EventDoneData size %d", edd->fDataSize);
604           delete [] reinterpret_cast<char*>(edd);
605           edd=NULL;
606         }
607
608         // remove event data block
609         fBlockDataArray.pop_back();
610
611         // check for forwarded blocks.
612         // loop over all output blocks and check
613         // 1. for duplicate blocks (pointing to same location in output buffer
614         //    or to the same buffer)
615         // 2. for blocks forwarded from the input.
616         if (iResult>=0 && outputBlocks) {
617           if (fListTargets.First()!=NULL) {
618             AliHLTComponentBlockDataList segments;
619             for (AliHLTUInt32_t oblock=0; oblock<outputBlockCnt; oblock++) {
620               // consistency check for data reference
621               if (outputBlocks[oblock].fPtr!=NULL && outputBlocks[oblock].fPtr!=pTgtBuffer &&
622                   outputBlocks[oblock].fOffset!=0) {
623                 HLTWarning("output block %s 0x%08x has inconsistent data reference ptr=%p offset=0x%08x: "
624                            "for new blocks use offset only, forwarded blocks have fPtr set only",
625                            AliHLTComponent::DataType2Text(outputBlocks[oblock].fDataType).c_str(),
626                            outputBlocks[oblock].fSpecification,
627                            outputBlocks[oblock].fPtr, outputBlocks[oblock].fOffset);
628               }
629
630               // check for duplicates in the output
631               AliHLTUInt32_t checkblock=0;
632               for (; checkblock<oblock; checkblock++) {
633                 if (outputBlocks[oblock].fPtr!=NULL && outputBlocks[oblock].fPtr!=pTgtBuffer &&
634                     outputBlocks[checkblock].fPtr==outputBlocks[oblock].fPtr) {
635                   if (outputBlocks[checkblock].fSize!=outputBlocks[oblock].fSize ||
636                       outputBlocks[checkblock].fDataType!=outputBlocks[oblock].fDataType) {
637                     HLTWarning("output blocks %d (%s 0x%08x) and %d (%s 0x%08x) have identical data references ptr=%p "
638                                "but differ in data type and/or size: %d vs. %d",
639                                oblock,
640                                AliHLTComponent::DataType2Text(outputBlocks[oblock].fDataType).c_str(),
641                                outputBlocks[oblock].fSpecification,
642                                checkblock,
643                                AliHLTComponent::DataType2Text(outputBlocks[checkblock].fDataType).c_str(),
644                                outputBlocks[checkblock].fSpecification,
645                                outputBlocks[oblock].fPtr,
646                                outputBlocks[oblock].fSize,
647                                outputBlocks[checkblock].fSize);
648                   }
649                   // ignore from the second copy
650                   break;
651                 }
652               }
653               if (checkblock<oblock) continue;
654
655               // search for the forwarded data blocks
656               // new data blocks are announced to the data buffer, forwarded data blocks
657               // to the publisher task. The publisher task of a forwarded data block is
658               // removed from the list in order to keep the buffer open. It will be releases
659               // when the subscribing task releases it
660               AliHLTUInt32_t iblock=0;
661               for (; iblock<fBlockDataArray.size(); iblock++) {
662                 if (outputBlocks[oblock].fDataType==kAliHLTDataTypeEvent) {
663                   // the event type data block is ignored if it was forwarded
664                   break;
665                 }
666                 if (fBlockDataArray[iblock].fPtr==outputBlocks[oblock].fPtr) {
667                   assert(subscribedTaskList[iblock]!=NULL);
668                   if (subscribedTaskList[iblock]==NULL) continue;
669                   HLTDebug("forward segment %d (source task %s %p) to data buffer %p", iblock, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
670                   fpDataBuffer->Forward(subscribedTaskList[iblock], &fBlockDataArray[iblock]);
671                   subscribedTaskList[iblock]=NULL; // not to be released in the loop further down
672                   break;
673                 }
674               }
675               if (iblock==fBlockDataArray.size()) segments.push_back(outputBlocks[oblock]);
676             }
677             if (pTgtBuffer && segments.size()>0) {
678               iResult=fpDataBuffer->SetSegments(pTgtBuffer, &segments[0], segments.size());
679             }
680           } else {
681             // no forwarding, actually we dont even need to keep the data, this is a
682             // dead end (fListTargets empty)
683             //iResult=fpDataBuffer->SetSegments(pTgtBuffer, outputBlocks, outputBlockCnt);
684           }
685           delete [] outputBlocks; outputBlocks=NULL; outputBlockCnt=0;
686         } else {
687           fpDataBuffer->Reset();
688         }
689         if (fListTargets.First()!=NULL) {
690           if (iSOR>=0 && subscribedTaskList[iSOR]!=NULL) {
691             HLTDebug("forward SOR event segment %d (source task %s %p) to data buffer %p", iSOR, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
692             fpDataBuffer->Forward(subscribedTaskList[iSOR], &fBlockDataArray[iSOR]);
693             subscribedTaskList[iSOR]=NULL; // not to be released in the loop further down
694           }
695           if (iEOR>=0 && subscribedTaskList[iEOR]!=NULL) {
696             HLTDebug("forward EOR event (%s) segment %d (source task %s %p) to data buffer %p", AliHLTComponent::DataType2Text(fBlockDataArray[iEOR].fDataType).c_str(), iEOR, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
697             fpDataBuffer->Forward(subscribedTaskList[iEOR], &fBlockDataArray[iEOR]);
698             subscribedTaskList[iEOR]=NULL; // not to be released in the loop further down
699           }
700           if (iECS>=0 && subscribedTaskList[iECS]!=NULL) {
701             HLTDebug("forward EOR event (%s) segment %d (source task %s %p) to data buffer %p", AliHLTComponent::DataType2Text(fBlockDataArray[iECS].fDataType).c_str(), iECS, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
702             fpDataBuffer->Forward(subscribedTaskList[iECS], &fBlockDataArray[iECS]);
703             subscribedTaskList[iECS]=NULL; // not to be released in the loop further down
704           }
705         }
706       } else {
707         HLTError("no target buffer available");
708         iResult=-EFAULT;
709       }
710     } while (iResult==-ENOSPC && iNofTrial++<1);
711     }
712
713     // now release all buffers which we have subscribed to
714     iSourceDataBlock=0;
715     AliHLTTaskPList::iterator element;
716     while ((element=subscribedTaskList.begin())!=subscribedTaskList.end()) {
717       pSrcTask=*element;
718       if (pSrcTask) {
719         int iTempRes=0;
720         if ((iTempRes=pSrcTask->Release(&fBlockDataArray[iSourceDataBlock], this))>=0) {
721           HLTDebug("successfully released segment of task %s (%p)", pSrcTask->GetName(), pSrcTask);
722         } else {
723           HLTError("realease of task %s (%p) failed with error %d", pSrcTask->GetName(), pSrcTask, iTempRes);
724         }
725       }
726       subscribedTaskList.erase(element);
727       iSourceDataBlock++;
728     }
729     if (subscribedTaskList.size()>0) {
730       HLTError("could not release all data buffers");
731     }
732   } else {
733     HLTError("internal failure (not initialized component %p, data buffer %p)", fpComponent, fpDataBuffer);
734     iResult=-EFAULT;
735   }
736   return iResult;
737 }
738
739 int AliHLTTask::GetNofMatchingDataBlocks(const AliHLTTask* pConsumerTask) const
740 {
741   // see header file for function documentation
742   int iResult=0;
743   if (pConsumerTask) {
744     if (fpDataBuffer) {
745       iResult=fpDataBuffer->FindMatchingDataBlocks(pConsumerTask->GetComponent(), NULL);
746     } else {
747       HLTFatal("internal data buffer missing");
748       iResult=-EFAULT;
749     }
750   } else {
751     iResult=-EINVAL;
752   }
753   return iResult;
754 }
755
756 int AliHLTTask::GetNofMatchingDataTypes(const AliHLTTask* pConsumerTask) const
757 {
758   // see header file for function documentation
759   int iResult=0;
760   if (pConsumerTask) {
761     AliHLTComponent* pComponent=GetComponent();
762     if (!pComponent) {
763       // init ?
764       HLTError("component not initialized");
765       iResult=-EFAULT;
766     }
767     if (pComponent) {
768       iResult=pComponent->FindMatchingDataTypes(pConsumerTask->GetComponent(), NULL);
769     } else {
770       HLTFatal("task initialization failed");
771       iResult=-EFAULT;
772     }
773   } else {
774     iResult=-EINVAL;
775   }
776   return iResult;
777 }
778
779 int AliHLTTask::Subscribe(const AliHLTTask* pConsumerTask, AliHLTComponentBlockDataList& blockDescList)
780 {
781   // see header file for function documentation
782   int iResult=0;
783   if (pConsumerTask) {
784     if (fpDataBuffer) {
785       iResult=fpDataBuffer->Subscribe(pConsumerTask->GetComponent(), blockDescList);
786     } else {
787       HLTFatal("internal data buffer missing");
788       iResult=-EFAULT;
789     }
790   } else {
791     iResult=-EINVAL;
792   }
793   return iResult;
794 }
795
796 int AliHLTTask::Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTTask* pConsumerTask)
797 {
798   // see header file for function documentation
799   int iResult=0;
800   if (pConsumerTask && pBlockDesc) {
801     if (fpDataBuffer) {
802       iResult=fpDataBuffer->Release(pBlockDesc, pConsumerTask->GetComponent(), this);
803     } else {
804       HLTFatal("internal data buffer missing");
805       iResult=-EFAULT;
806     }
807   } else {
808     iResult=-EINVAL;
809   }
810   return iResult;
811 }
812
813 void AliHLTTask::PrintStatus()
814 {
815   // see header file for function documentation
816   HLTLogKeyword("task properties");
817   AliHLTComponent* pComponent=GetComponent();
818   if (pComponent) {
819     HLTMessage("     component: %s (%p)", pComponent->GetComponentID(), pComponent);
820   } else {
821     HLTMessage("     no component set!");
822   }
823   if (fpConfiguration) {
824     AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
825     while (pSrc) {
826       const char* pQualifier="unresolved";
827       if (FindDependency(pSrc->GetName()))
828         pQualifier="resolved";
829       HLTMessage("     source: %s (%s)", pSrc->GetName(), pQualifier);
830       pSrc=fpConfiguration->GetNextSource();
831     }
832     TObjLink* lnk = fListTargets.FirstLink();
833     while (lnk) {
834       TObject *obj = lnk->GetObject();
835       HLTMessage("     target: %s", obj->GetName());
836       lnk = lnk->Next();
837     }
838   } else {
839     HLTMessage("     task not initialized");
840   }
841 }
842
843 int AliHLTTask::CustomInit(AliHLTComponentHandler* /*pCH*/)
844 {
845   // default implementation nothing to do
846   return 0;
847 }
848
849 int AliHLTTask::CustomCleanup()
850 {
851   // default implementation nothing to do
852   return 0;
853 }
854
855 int AliHLTTask::LoggingVarargs(AliHLTComponentLogSeverity severity, 
856                                     const char* originClass, const char* originFunc,
857                                     const char* file, int line, ... ) const
858 {
859   // see header file for function documentation
860   int iResult=0;
861
862   va_list args;
863   va_start(args, line);
864
865   AliHLTLogging::SetLogString(this, " (%p)", "%s_pfmt_: ", GetName());
866   iResult=SendMessage(severity, originClass, originFunc, file, line, AliHLTLogging::BuildLogString(NULL, args, true /*append*/));
867   va_end(args);
868
869   return iResult;
870 }