]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTTask.cxx
adding a member for the active CTP trigger mask to the CTP data object and setting...
[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)
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
467     // subscribe to all source tasks
468     fBlockDataArray.clear();
469     while (lnk && iResult>=0) {
470       pSrcTask=(AliHLTTask*)lnk->GetObject();
471       if (pSrcTask) {
472         int iMatchingDB=pSrcTask->GetNofMatchingDataBlocks(this);
473         if (iMatchingDB<0) {
474           HLTError("task %s (%p): error getting no of matching data blocks from task %s (%p), error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iMatchingDB);
475           iResult=iMatchingDB;
476           break;
477         } else if (iMatchingDB==0) {
478           HLTDebug("source task %s (%p) does not provide any matching data type for task %s (%p)", pSrcTask->GetName(), pSrcTask, GetName(), this);
479         }
480         if ((iResult=pSrcTask->Subscribe(this, fBlockDataArray))>=0) {
481           iSOR=iEOR=-1;
482           AliHLTComponentBlockDataList::iterator block=fBlockDataArray.begin();
483           for (int i=0; block!=fBlockDataArray.end(); i++) {
484             bool bRemove=0;
485             bRemove|=(*block).fDataType==kAliHLTDataTypeSOR && !(iSOR<0 && (iSOR=i)>=0);
486             bRemove|=(*block).fDataType==kAliHLTDataTypeEOR && !(iEOR<0 && (iEOR=i)>=0);
487             //HLTInfo("block %d, iSOR=%d iEOR=%d remove=%d", i, iSOR, iEOR, bRemove);
488             if (i<iSourceDataBlock) {
489               assert(!bRemove);
490             } else if (bRemove) {
491               HLTDebug("remove duplicated event %s (%d)", AliHLTComponent::DataType2Text((*block).fDataType).c_str(), i);
492               pSrcTask->Release(&(*block), this);
493               block=fBlockDataArray.erase(block);
494               continue;
495             } else {
496             iInputDataVolume+=(*block).fSize;
497             // put the source task as many times into the list as it provides data blocks
498             // makes the bookkeeping for the data release easier
499             subscribedTaskList.push_back(pSrcTask);
500             }
501             block++;
502           }
503           HLTDebug("Task %s (%p) successfully subscribed to %d data block(s) of task %s (%p)", GetName(), this, iResult, pSrcTask->GetName(), pSrcTask);
504           iSourceDataBlock=fBlockDataArray.size();        
505           iResult=0;
506         } else {
507           HLTError("Task %s (%p): subscription to task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iResult);
508           iResult=-EFAULT;
509         }
510       } else {
511         HLTFatal("fatal internal error in ROOT list handling");
512         iResult=-EFAULT;
513       }
514       lnk=lnk->Next();
515     }    
516
517     // process the event
518     int iNofTrial=0; // repeat processing if component returns -ENOSPC
519     AliHLTUInt32_t iLastOutputDataSize=0;
520     if (iResult>=0) {
521     do {
522       long unsigned int iOutputDataSize=0;
523       AliHLTConfiguration* pConf=GetConf();
524       // check if there was a buffer size specified, query output size
525       // estimator from component otherwize
526       if (pConf && pConf->GetOutputBufferSize()>=0) {
527         iOutputDataSize=pConf->GetOutputBufferSize();
528       } else {
529       long unsigned int iConstBase=0;
530       double fInputMultiplier=0;
531       if (pComponent->GetComponentType()!=AliHLTComponent::kSink) {
532         pComponent->GetOutputDataSize(iConstBase, fInputMultiplier);
533         // add a small margin to the buffer to allow optional component
534         // statistics
535         iConstBase+=100;
536 #if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
537         for (AliHLTComponentBlockDataList::iterator element=fBlockDataArray.begin();
538              element!=fBlockDataArray.end(); element++) {
539           if (element->fDataType==kAliHLTDataTypeComponentStatistics) {
540             iConstBase+=element->fSize;
541           }
542         }
543 #endif
544       }
545       if (fInputMultiplier<0) {
546         HLTWarning("ignoring negative input multiplier");
547         fInputMultiplier=0;
548       }
549       iOutputDataSize=int(fInputMultiplier*iInputDataVolume) + iConstBase;
550       //HLTDebug("task %s: reqired output size %d", GetName(), iOutputDataSize);
551       }
552       if (iNofTrial>0) {
553         // dont process again if the buffer size is the same
554         if (iLastOutputDataSize==iOutputDataSize) break;
555         HLTImportant("processing event %d again with buffer size %d", eventNo, iOutputDataSize);
556       }
557       AliHLTUInt8_t* pTgtBuffer=NULL;
558       if (iOutputDataSize>0) pTgtBuffer=fpDataBuffer->GetTargetBuffer(iOutputDataSize);
559       //HLTDebug("provided raw buffer %p", pTgtBuffer);
560       AliHLTComponentEventData evtData;
561       AliHLTComponent::FillEventData(evtData);
562       if (eventNo>=0)
563         evtData.fEventID=(AliHLTEventID_t)eventNo;
564       evtData.fEventCreation_s=static_cast<AliHLTUInt32_t>(time(NULL));
565       AliHLTComponentTriggerData trigData;
566       AliHLTEventTriggerData evtTrigData;
567       trigData.fStructSize=sizeof(trigData);
568       trigData.fDataSize=sizeof(AliHLTEventTriggerData);
569       memset(&evtTrigData, 0, trigData.fDataSize);
570       evtTrigData.fCommonHeaderWordCnt=gkAliHLTCommonHeaderCount;
571       trigData.fData=&evtTrigData;
572       iLastOutputDataSize=iOutputDataSize;
573       AliHLTUInt32_t size=iOutputDataSize;
574       AliHLTUInt32_t outputBlockCnt=0;
575       AliHLTComponentBlockData* outputBlocks=NULL;
576       AliHLTComponentEventDoneData* edd=NULL;
577       if (pTgtBuffer!=NULL || iOutputDataSize==0) {
578         // add event type data block
579         // the block is removed immediately after processing from the list
580         AliHLTComponentBlockData eventTypeBlock;
581         AliHLTComponent::FillBlockData(eventTypeBlock);
582         // Note: no payload!
583         eventTypeBlock.fDataType=kAliHLTDataTypeEvent;
584         eventTypeBlock.fSpecification=eventType;
585         fBlockDataArray.push_back(eventTypeBlock);
586
587         // process
588         evtData.fBlockCnt=fBlockDataArray.size();
589         iResult=pComponent->ProcessEvent(evtData, &fBlockDataArray[0], trigData, pTgtBuffer, size, outputBlockCnt, outputBlocks, edd);
590         HLTDebug("component %s ProcessEvent finnished (%d): size=%d blocks=%d", pComponent->GetComponentID(), iResult, size, outputBlockCnt);
591
592         // EventDoneData is for the moment ignored in AliHLTSystem
593         if (edd) {
594           HLTDebug("got EventDoneData size %d", edd->fDataSize);
595           delete [] reinterpret_cast<char*>(edd);
596           edd=NULL;
597         }
598
599         // remove event data block
600         fBlockDataArray.pop_back();
601
602         // check for forwarded blocks.
603         // loop over all output blocks and check
604         // 1. for duplicate blocks (pointing to same location in output buffer
605         //    or to the same buffer)
606         // 2. for blocks forwarded from the input.
607         if (iResult>=0 && outputBlocks) {
608           if (fListTargets.First()!=NULL) {
609             AliHLTComponentBlockDataList segments;
610             for (AliHLTUInt32_t oblock=0; oblock<outputBlockCnt; oblock++) {
611               // consistency check for data reference
612               if (outputBlocks[oblock].fPtr!=NULL && outputBlocks[oblock].fPtr!=pTgtBuffer &&
613                   outputBlocks[oblock].fOffset!=0) {
614                 HLTWarning("output block %s 0x%08x has inconsistent data reference ptr=%p offset=0x%08x: "
615                            "for new blocks use offset only, forwarded blocks have fPtr set only",
616                            AliHLTComponent::DataType2Text(outputBlocks[oblock].fDataType).c_str(),
617                            outputBlocks[oblock].fSpecification,
618                            outputBlocks[oblock].fPtr, outputBlocks[oblock].fOffset);
619               }
620
621               // check for duplicates in the output
622               AliHLTUInt32_t checkblock=0;
623               for (; checkblock<oblock; checkblock++) {
624                 if (outputBlocks[oblock].fPtr!=NULL && outputBlocks[oblock].fPtr!=pTgtBuffer &&
625                     outputBlocks[checkblock].fPtr==outputBlocks[oblock].fPtr) {
626                   if (outputBlocks[checkblock].fSize!=outputBlocks[oblock].fSize ||
627                       outputBlocks[checkblock].fDataType!=outputBlocks[oblock].fDataType) {
628                     HLTWarning("output blocks %d (%s 0x%08x) and %d (%s 0x%08x) have identical data references ptr=%p "
629                                "but differ in data type and/or size: %d vs. %d",
630                                oblock,
631                                AliHLTComponent::DataType2Text(outputBlocks[oblock].fDataType).c_str(),
632                                outputBlocks[oblock].fSpecification,
633                                checkblock,
634                                AliHLTComponent::DataType2Text(outputBlocks[checkblock].fDataType).c_str(),
635                                outputBlocks[checkblock].fSpecification,
636                                outputBlocks[oblock].fPtr,
637                                outputBlocks[oblock].fSize,
638                                outputBlocks[checkblock].fSize);
639                   }
640                   // ignore from the second copy
641                   break;
642                 }
643               }
644               if (checkblock<oblock) continue;
645
646               // search for the forwarded data blocks
647               // new data blocks are announced to the data buffer, forwarded data blocks
648               // to the publisher task. The publisher task of a forwarded data block is
649               // removed from the list in order to keep the buffer open. It will be releases
650               // when the subscribing task releases it
651               AliHLTUInt32_t iblock=0;
652               for (; iblock<fBlockDataArray.size(); iblock++) {
653                 if (outputBlocks[oblock].fDataType==kAliHLTDataTypeEvent) {
654                   // the event type data block is ignored if it was forwarded
655                   break;
656                 }
657                 if (fBlockDataArray[iblock].fPtr==outputBlocks[oblock].fPtr) {
658                   assert(subscribedTaskList[iblock]!=NULL);
659                   if (subscribedTaskList[iblock]==NULL) continue;
660                   HLTDebug("forward segment %d (source task %s %p) to data buffer %p", iblock, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
661                   fpDataBuffer->Forward(subscribedTaskList[iblock], &fBlockDataArray[iblock]);
662                   subscribedTaskList[iblock]=NULL; // not to be released in the loop further down
663                   break;
664                 }
665               }
666               if (iblock==fBlockDataArray.size()) segments.push_back(outputBlocks[oblock]);
667             }
668             if (pTgtBuffer && segments.size()>0) {
669               iResult=fpDataBuffer->SetSegments(pTgtBuffer, &segments[0], segments.size());
670             }
671           } else {
672             // no forwarding, actually we dont even need to keep the data, this is a
673             // dead end (fListTargets empty)
674             //iResult=fpDataBuffer->SetSegments(pTgtBuffer, outputBlocks, outputBlockCnt);
675           }
676           delete [] outputBlocks; outputBlocks=NULL; outputBlockCnt=0;
677         } else {
678           fpDataBuffer->Reset();
679         }
680         if (fListTargets.First()!=NULL) {
681           if (iSOR>=0 && subscribedTaskList[iSOR]!=NULL) {
682             HLTDebug("forward SOR event segment %d (source task %s %p) to data buffer %p", iSOR, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
683             fpDataBuffer->Forward(subscribedTaskList[iSOR], &fBlockDataArray[iSOR]);
684             subscribedTaskList[iSOR]=NULL; // not to be released in the loop further down
685           }
686           if (iEOR>=0 && subscribedTaskList[iEOR]!=NULL) {
687             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);
688             fpDataBuffer->Forward(subscribedTaskList[iEOR], &fBlockDataArray[iEOR]);
689             subscribedTaskList[iEOR]=NULL; // not to be released in the loop further down
690           }
691         }
692       } else {
693         HLTError("no target buffer available");
694         iResult=-EFAULT;
695       }
696     } while (iResult==-ENOSPC && iNofTrial++<1);
697     }
698
699     // now release all buffers which we have subscribed to
700     iSourceDataBlock=0;
701     AliHLTTaskPList::iterator element;
702     while ((element=subscribedTaskList.begin())!=subscribedTaskList.end()) {
703       pSrcTask=*element;
704       if (pSrcTask) {
705         int iTempRes=0;
706         if ((iTempRes=pSrcTask->Release(&fBlockDataArray[iSourceDataBlock], this))>=0) {
707           HLTDebug("successfully released segment of task %s (%p)", pSrcTask->GetName(), pSrcTask);
708         } else {
709           HLTError("realease of task %s (%p) failed with error %d", pSrcTask->GetName(), pSrcTask, iTempRes);
710         }
711       }
712       subscribedTaskList.erase(element);
713       iSourceDataBlock++;
714     }
715     if (subscribedTaskList.size()>0) {
716       HLTError("could not release all data buffers");
717     }
718   } else {
719     HLTError("internal failure (not initialized component %p, data buffer %p)", fpComponent, fpDataBuffer);
720     iResult=-EFAULT;
721   }
722   return iResult;
723 }
724
725 int AliHLTTask::GetNofMatchingDataBlocks(const AliHLTTask* pConsumerTask) const
726 {
727   // see header file for function documentation
728   int iResult=0;
729   if (pConsumerTask) {
730     if (fpDataBuffer) {
731       iResult=fpDataBuffer->FindMatchingDataBlocks(pConsumerTask->GetComponent(), NULL);
732     } else {
733       HLTFatal("internal data buffer missing");
734       iResult=-EFAULT;
735     }
736   } else {
737     iResult=-EINVAL;
738   }
739   return iResult;
740 }
741
742 int AliHLTTask::GetNofMatchingDataTypes(const AliHLTTask* pConsumerTask) const
743 {
744   // see header file for function documentation
745   int iResult=0;
746   if (pConsumerTask) {
747     AliHLTComponent* pComponent=GetComponent();
748     if (!pComponent) {
749       // init ?
750       HLTError("component not initialized");
751       iResult=-EFAULT;
752     }
753     if (pComponent) {
754       iResult=pComponent->FindMatchingDataTypes(pConsumerTask->GetComponent(), NULL);
755     } else {
756       HLTFatal("task initialization failed");
757       iResult=-EFAULT;
758     }
759   } else {
760     iResult=-EINVAL;
761   }
762   return iResult;
763 }
764
765 int AliHLTTask::Subscribe(const AliHLTTask* pConsumerTask, AliHLTComponentBlockDataList& blockDescList)
766 {
767   // see header file for function documentation
768   int iResult=0;
769   if (pConsumerTask) {
770     if (fpDataBuffer) {
771       iResult=fpDataBuffer->Subscribe(pConsumerTask->GetComponent(), blockDescList);
772     } else {
773       HLTFatal("internal data buffer missing");
774       iResult=-EFAULT;
775     }
776   } else {
777     iResult=-EINVAL;
778   }
779   return iResult;
780 }
781
782 int AliHLTTask::Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTTask* pConsumerTask)
783 {
784   // see header file for function documentation
785   int iResult=0;
786   if (pConsumerTask && pBlockDesc) {
787     if (fpDataBuffer) {
788       iResult=fpDataBuffer->Release(pBlockDesc, pConsumerTask->GetComponent(), this);
789     } else {
790       HLTFatal("internal data buffer missing");
791       iResult=-EFAULT;
792     }
793   } else {
794     iResult=-EINVAL;
795   }
796   return iResult;
797 }
798
799 void AliHLTTask::PrintStatus()
800 {
801   // see header file for function documentation
802   HLTLogKeyword("task properties");
803   AliHLTComponent* pComponent=GetComponent();
804   if (pComponent) {
805     HLTMessage("     component: %s (%p)", pComponent->GetComponentID(), pComponent);
806   } else {
807     HLTMessage("     no component set!");
808   }
809   if (fpConfiguration) {
810     AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
811     while (pSrc) {
812       const char* pQualifier="unresolved";
813       if (FindDependency(pSrc->GetName()))
814         pQualifier="resolved";
815       HLTMessage("     source: %s (%s)", pSrc->GetName(), pQualifier);
816       pSrc=fpConfiguration->GetNextSource();
817     }
818     TObjLink* lnk = fListTargets.FirstLink();
819     while (lnk) {
820       TObject *obj = lnk->GetObject();
821       HLTMessage("     target: %s", obj->GetName());
822       lnk = lnk->Next();
823     }
824   } else {
825     HLTMessage("     task not initialized");
826   }
827 }
828
829 int AliHLTTask::CustomInit(AliHLTComponentHandler* /*pCH*/)
830 {
831   // default implementation nothing to do
832   return 0;
833 }
834
835 int AliHLTTask::CustomCleanup()
836 {
837   // default implementation nothing to do
838   return 0;
839 }
840
841 int AliHLTTask::LoggingVarargs(AliHLTComponentLogSeverity severity, 
842                                     const char* originClass, const char* originFunc,
843                                     const char* file, int line, ... ) const
844 {
845   // see header file for function documentation
846   int iResult=0;
847
848   va_list args;
849   va_start(args, line);
850
851   AliHLTLogging::SetLogString("%s (%p): ", GetName(), this);
852   iResult=SendMessage(severity, originClass, originFunc, file, line, AliHLTLogging::BuildLogString(NULL, args, true /*append*/));
853   va_end(args);
854
855   return iResult;
856 }