bugfix: initialization of trigger data struct
[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 "AliHLTTask.h"
40 #include "AliHLTConfiguration.h"
41 #include "AliHLTComponent.h"
42 #include "AliHLTComponentHandler.h"
43 #include "TList.h"
44
45 /** ROOT macro for the implementation of ROOT specific class methods */
46 ClassImp(AliHLTTask)
47
48 AliHLTTask::AliHLTTask()
49   :
50   fpConfiguration(NULL),
51   fpComponent(NULL),
52   fpDataBuffer(NULL),
53   fListTargets(),
54   fListDependencies(),
55   fBlockDataArray()
56 {
57   // see header file for class documentation
58   // or
59   // refer to README to build package
60   // or
61   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
62 }
63
64 AliHLTTask::AliHLTTask(AliHLTConfiguration* pConf)
65   :
66   fpConfiguration(pConf),
67   fpComponent(NULL),
68   fpDataBuffer(NULL),
69   fListTargets(),
70   fListDependencies(),
71   fBlockDataArray()
72 {
73   // see header file for function documentation
74 }
75
76 AliHLTTask::~AliHLTTask()
77 {
78   // see header file for function documentation
79   TObjLink* lnk=fListDependencies.FirstLink();
80
81   while (lnk!=NULL) {
82     AliHLTTask* pTask=(AliHLTTask*)lnk->GetObject();
83     pTask->UnsetTarget(this);
84     lnk=lnk->Next();
85   }
86   lnk=fListTargets.FirstLink();
87
88   while (lnk!=NULL) {
89     AliHLTTask* pTask=(AliHLTTask*)lnk->GetObject();
90     pTask->UnsetDependency(this);
91     lnk=lnk->Next();
92   }
93
94   if (fpComponent) delete fpComponent;
95   fpComponent=NULL;
96 }
97
98 int AliHLTTask::Init(AliHLTConfiguration* pConf, AliHLTComponentHandler* pCH)
99 {
100   // see header file for function documentation
101   int iResult=0;
102   if (fpConfiguration!=NULL && pConf!=NULL && fpConfiguration!=pConf) {
103     HLTWarning("overriding existing reference to configuration object %p (%s) by %p",
104                fpConfiguration, GetName(), pConf);
105   }
106   if (pConf!=NULL) fpConfiguration=pConf;
107   if (fpConfiguration) {
108     if (pCH) {
109       int argc=0;
110       const char** argv=NULL;
111       if ((iResult=fpConfiguration->GetArguments(&argv))>=0) {
112         argc=iResult; // just to make it clear
113         // TODO: we have to think about the optional environment parameter,
114         // currently just set to NULL. 
115         iResult=pCH->CreateComponent(fpConfiguration->GetComponentID(), NULL, argc, argv, fpComponent);
116         if (fpComponent && iResult>=0) {
117           //HLTDebug("component %s (%p) created", fpComponent->GetComponentID(), fpComponent); 
118         } else {
119           //HLTError("can not find component \"%s\" (%d)", fpConfiguration->GetComponentID(), iResult);
120         }
121       } else {
122         HLTError("can not get argument list for configuration %s (%s)", fpConfiguration->GetName(), fpConfiguration->GetComponentID());
123         iResult=-EINVAL;
124       }
125     } else {
126       HLTError("component handler instance needed for task initialization");
127       iResult=-EINVAL;
128     }
129   } else {
130     HLTError("configuration object instance needed for task initialization");
131     iResult=-EINVAL;
132   }
133   if (iResult>=0) {
134     iResult=CustomInit(pCH);
135   }
136   return iResult;
137 }
138
139 int AliHLTTask::Deinit()
140 {
141   // see header file for function documentation
142   int iResult=0;
143   CustomCleanup();
144   AliHLTComponent* pComponent=GetComponent();
145   fpComponent=NULL;
146   if (pComponent) {
147     //HLTDebug("delete component %s (%p)", pComponent->GetComponentID(), pComponent); 
148     pComponent->Deinit();
149     delete pComponent;
150   } else {
151     HLTWarning("task %s (%p) doesn't seem to be in initialized", GetName(), this);
152   }
153   return iResult;
154 }
155
156 const char *AliHLTTask::GetName() const
157 {
158   // see header file for function documentation
159   if (fpConfiguration)
160     return fpConfiguration->GetName();
161   return TObject::GetName();
162 }
163
164 AliHLTConfiguration* AliHLTTask::GetConf() const
165 {
166   // see header file for function documentation
167   return fpConfiguration;
168 }
169
170 AliHLTComponent* AliHLTTask::GetComponent() const
171 {
172   // see header file for function documentation
173   return fpComponent;
174 }
175
176 AliHLTTask* AliHLTTask::FindDependency(const char* id)
177 {
178   // see header file for function documentation
179   AliHLTTask* pTask=NULL;
180   if (id) {
181     pTask=(AliHLTTask*)fListDependencies.FindObject(id);
182   }
183   return pTask;
184 }
185
186 int AliHLTTask::FollowDependency(const char* id, TList* pTgtList)
187 {
188   // see header file for function documentation
189   int iResult=0;
190   if (id) {
191     AliHLTTask* pDep=NULL;
192     if ((pDep=(AliHLTTask*)fListDependencies.FindObject(id))!=NULL) {
193       if (pTgtList) pTgtList->Add(pDep);
194       iResult++;
195     } else {
196       TObjLink* lnk=fListDependencies.FirstLink();
197       while (lnk && iResult==0) {
198         pDep=(AliHLTTask*)lnk->GetObject();
199         if (pDep) {
200           if ((iResult=pDep->FollowDependency(id, pTgtList))>0) {
201             if (pTgtList) pTgtList->AddFirst(pDep);
202             iResult++;
203           }
204         } else {
205           iResult=-EFAULT;
206         }
207         lnk=lnk->Next();
208       }
209     }
210   } else {
211     iResult=-EINVAL;
212   }
213   return iResult;
214 }
215
216 void AliHLTTask::PrintDependencyTree(const char* id, int bFromConfiguration)
217 {
218   // see header file for function documentation
219   HLTLogKeyword("task dependencies");
220   int iResult=0;
221   TList tgtList;
222   if (bFromConfiguration) {
223     if (fpConfiguration)
224       iResult=fpConfiguration->FollowDependency(id, &tgtList);
225     else
226       iResult=-EFAULT;
227   } else
228     iResult=FollowDependency(id, &tgtList);
229   if (iResult>0) {
230     HLTMessage("     task \"%s\": dependency level %d ", GetName(), iResult);
231     TObjLink* lnk=tgtList.FirstLink();
232     int i=iResult;
233     char* pSpace = new char[iResult+1];
234     if (pSpace) {
235       memset(pSpace, 32, iResult);
236       pSpace[i]=0;
237       while (lnk) {
238         TObject* obj=lnk->GetObject();
239         HLTMessage("     %s^-- %s ", &pSpace[i--], obj->GetName());
240         lnk=lnk->Next();
241       }
242       delete [] pSpace;
243     } else {
244       iResult=-ENOMEM;
245     }
246   }
247 }
248
249 int AliHLTTask::SetDependency(AliHLTTask* pDep)
250 {
251   // see header file for function documentation
252   int iResult=0;
253   if (pDep) {
254     if (FindDependency(pDep->GetName())==NULL) {
255       fListDependencies.Add(pDep);
256     } else {
257       iResult=-EEXIST;
258     }
259   } else {
260     iResult=-EINVAL;
261   }
262   return iResult;
263 }
264
265 int AliHLTTask::UnsetDependency(AliHLTTask* pDep)
266 {
267   // see header file for function documentation
268   fListDependencies.Remove(pDep);
269   if (fpConfiguration) {
270     fpConfiguration->InvalidateSources();
271   }
272   return 0;
273 }
274
275 int AliHLTTask::CheckDependencies()
276 {
277   // see header file for function documentation
278   int iResult=0;
279   AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
280   while (pSrc) {
281     if (FindDependency(pSrc->GetName())==NULL) {
282       //HLTDebug("dependency \"%s\" unresolved", pSrc->GetName());
283       iResult++;
284     }
285     pSrc=fpConfiguration->GetNextSource();
286   }
287   return iResult;
288 }
289
290
291 int AliHLTTask::Depends(AliHLTTask* pTask)
292 {
293   // see header file for function documentation
294   int iResult=0;
295   if (pTask) {
296     if (fpConfiguration) {
297       iResult=fpConfiguration->GetSource(pTask->GetName())!=NULL;
298       if (iResult>0) {
299         //HLTDebug("task  \"%s\" depends on \"%s\"", GetName(), pTask->GetName());
300       } else {
301         //HLTDebug("task  \"%s\" independend of \"%s\"", GetName(), pTask->GetName());
302       }
303     } else {
304       iResult=-EFAULT;
305     }
306   } else {
307     iResult=-EINVAL;
308   }
309   return iResult;
310 }
311
312 AliHLTTask* AliHLTTask::FindTarget(const char* id)
313 {
314   // see header file for function documentation
315   AliHLTTask* pTask=NULL;
316   if (id) {
317     pTask=(AliHLTTask*)fListTargets.FindObject(id);
318   }
319   return pTask;
320 }
321
322 int AliHLTTask::SetTarget(AliHLTTask* pTgt)
323 {
324   // see header file for function documentation
325   int iResult=0;
326   if (pTgt) {
327     if (FindTarget(pTgt->GetName())==NULL) {
328       fListTargets.Add(pTgt);
329     } else {
330       iResult=-EEXIST;
331     }
332   } else {
333     iResult=-EINVAL;
334   }
335   return iResult;
336 }
337
338 int AliHLTTask::UnsetTarget(AliHLTTask* pTarget)
339 {
340   // see header file for function documentation
341   fListTargets.Remove(pTarget);
342   return 0;
343 }
344
345 int AliHLTTask::StartRun()
346 {
347   // see header file for function documentation
348   int iResult=0;
349   int iNofInputDataBlocks=0;
350   AliHLTComponent* pComponent=GetComponent();
351   if (pComponent) {
352     // determine the number of input data blocks provided from the source tasks
353     { // set scope for lnk as a local variable
354     TObjLink* lnk=fListDependencies.FirstLink();
355     while (lnk && iResult>=0) {
356       AliHLTTask* pSrcTask=(AliHLTTask*)lnk->GetObject();
357       if (pSrcTask) {
358         if ((iResult=pSrcTask->GetNofMatchingDataTypes(this))>0) {
359           iNofInputDataBlocks+=iResult;
360         } else if (iResult==0) {
361           HLTWarning("source task %s (%p) does not provide any matching data type for task %s (%p)", pSrcTask->GetName(), pSrcTask, GetName(), this);
362         } else {
363           HLTError("task %s (%p): error getting matching data types for source task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
364           iResult=-EFAULT;
365         }
366       }
367       lnk=lnk->Next();
368     }
369     }
370     if (iResult>=0) {
371       if (fBlockDataArray.size()>0) {
372         HLTWarning("block data array for task %s (%p) was not cleaned", GetName(), this);
373         fBlockDataArray.clear();
374       }
375
376       // component init
377       // the initialization of the component is done by the ComponentHandler after creation
378       // of the component.
379       //iResult=Init( AliHLTComponentEnvironment* environ, void* environ_param, int argc, const char** argv );
380
381       // allocate the data buffer, which controls the output buffer and subscriptions
382       if (iResult>=0) {
383         fpDataBuffer=new AliHLTDataBuffer;
384         if (fpDataBuffer!=NULL) {
385           fpDataBuffer->SetLocalLoggingLevel(GetLocalLoggingLevel());
386           HLTDebug("created data buffer %p for task %s (%p)", fpDataBuffer, GetName(), this);
387           TObjLink* lnk=fListTargets.FirstLink();
388           while (lnk && iResult>=0) {
389             AliHLTTask* pTgtTask=(AliHLTTask*)lnk->GetObject();
390             if (pTgtTask) {
391               if ((iResult=fpDataBuffer->SetConsumer(pTgtTask->GetComponent()))>=0) {
392               }
393             } else {
394               break;
395               iResult=-EFAULT;
396             }
397             lnk=lnk->Next();
398           }
399         } else {
400           HLTFatal("can not create data buffer object, memory allocation failed");
401           iResult=-ENOMEM;
402         }
403       }
404     }
405     if (iResult>=0) {
406       // send the SOR event
407       
408     }
409   } else {
410     HLTError("task %s (%p) does not have a component", GetName(), this);
411     iResult=-EFAULT;
412   }
413   return iResult;
414 }
415
416 int AliHLTTask::EndRun()
417 {
418   // see header file for function documentation
419   int iResult=0;
420   if (fBlockDataArray.size()>0) {
421     fBlockDataArray.clear();
422   }
423   if (fpDataBuffer) {
424     AliHLTDataBuffer* pBuffer=fpDataBuffer;
425     fpDataBuffer=NULL;
426     delete pBuffer;
427   }
428   return iResult;
429 }
430
431 int AliHLTTask::ProcessTask(Int_t eventNo)
432 {
433   // see header file for function documentation
434   int iResult=0;
435   AliHLTComponent* pComponent=GetComponent();
436   if (pComponent && fpDataBuffer) {
437     HLTDebug("Processing task %s (%p) fpDataBuffer %p", GetName(), this, fpDataBuffer);
438     fpDataBuffer->Reset();
439     int iSourceDataBlock=0;
440     int iInputDataVolume=0;
441
442     AliHLTTask* pSrcTask=NULL;
443     AliHLTTaskPList subscribedTaskList;
444     TObjLink* lnk=fListDependencies.FirstLink();
445
446     // instances of SOR and EOR events to be kept
447     int iSOR=-1;
448     int iEOR=-1;
449
450     // subscribe to all source tasks
451     fBlockDataArray.clear();
452     while (lnk && iResult>=0) {
453       pSrcTask=(AliHLTTask*)lnk->GetObject();
454       if (pSrcTask) {
455         int iMatchingDB=pSrcTask->GetNofMatchingDataBlocks(this);
456         if (iMatchingDB<0) {
457           HLTError("task %s (%p): error getting no of matching data blocks from task %s (%p), error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iMatchingDB);
458           iResult=iMatchingDB;
459           break;
460         } else if (iMatchingDB==0) {
461           HLTDebug("source task %s (%p) does not provide any matching data type for task %s (%p)", pSrcTask->GetName(), pSrcTask, GetName(), this);
462         }
463         if ((iResult=pSrcTask->Subscribe(this, fBlockDataArray))>=0) {
464           iSOR=iEOR=-1;
465           AliHLTComponentBlockDataList::iterator block=fBlockDataArray.begin();
466           for (int i=0; block!=fBlockDataArray.end(); i++) {
467             bool bRemove=0;
468             bRemove|=(*block).fDataType==kAliHLTDataTypeSOR && !(iSOR<0 && (iSOR=i)>=0);
469             bRemove|=(*block).fDataType==kAliHLTDataTypeEOR && !(iEOR<0 && (iEOR=i)>=0);
470             //HLTInfo("block %d, iSOR=%d iEOR=%d remove=%d", i, iSOR, iEOR, bRemove);
471             if (i<iSourceDataBlock) {
472               assert(!bRemove);
473             } else if (bRemove) {
474               HLTDebug("remove duplicated event %s (%d)", AliHLTComponent::DataType2Text((*block).fDataType).c_str(), i);
475               pSrcTask->Release(&(*block), this);
476               block=fBlockDataArray.erase(block);
477               continue;
478             } else {
479             iInputDataVolume+=(*block).fSize;
480             // put the source task as many times into the list as it provides data blocks
481             // makes the bookkeeping for the data release easier
482             subscribedTaskList.push_back(pSrcTask);
483             }
484             block++;
485           }
486           HLTDebug("Task %s (%p) successfully subscribed to %d data block(s) of task %s (%p)", GetName(), this, iResult, pSrcTask->GetName(), pSrcTask);
487           iSourceDataBlock=fBlockDataArray.size();        
488           iResult=0;
489         } else {
490           HLTError("Task %s (%p): subscription to task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iResult);
491           iResult=-EFAULT;
492         }
493       } else {
494         HLTFatal("fatal internal error in ROOT list handling");
495         iResult=-EFAULT;
496       }
497       lnk=lnk->Next();
498     }    
499
500     // process the event
501     int iNofTrial=0; // repeat processing if component returns -ENOSPC
502     AliHLTUInt32_t size=0;
503     if (iResult>=0) {
504     do {
505       long unsigned int iOutputDataSize=0;
506       AliHLTConfiguration* pConf=GetConf();
507       assert(pConf);
508       // check if there was a buffer size specified, query output size
509       // estimator from component otherwize
510       if (pConf && pConf->GetOutputBufferSize()>=0) {
511         iOutputDataSize=pConf->GetOutputBufferSize();
512       } else {
513       long unsigned int iConstBase=0;
514       double fInputMultiplier=0;
515       if (pComponent->GetComponentType()!=AliHLTComponent::kSink)
516         pComponent->GetOutputDataSize(iConstBase, fInputMultiplier);
517       if (fInputMultiplier<0) {
518         HLTWarning("ignoring negative input multiplier");
519         fInputMultiplier=0;
520       }
521       iOutputDataSize=int(fInputMultiplier*iInputDataVolume) + iConstBase;
522       //HLTDebug("task %s: reqired output size %d", GetName(), iOutputDataSize);
523       }
524       if (iNofTrial>0) {
525         // dont process again if the buffer size is the same
526         if (size==iOutputDataSize) break;
527         HLTInfo("processing task %s again with buffer size %d", GetName(), iOutputDataSize);
528       }
529       AliHLTUInt8_t* pTgtBuffer=NULL;
530       if (iOutputDataSize>0) pTgtBuffer=fpDataBuffer->GetTargetBuffer(iOutputDataSize);
531       //HLTDebug("provided raw buffer %p", pTgtBuffer);
532       AliHLTComponentEventData evtData;
533       AliHLTComponent::FillEventData(evtData);
534       evtData.fEventID=(AliHLTEventID_t)eventNo;
535       evtData.fBlockCnt=iSourceDataBlock;
536       AliHLTComponentTriggerData trigData;
537       trigData.fStructSize=sizeof(trigData);
538       trigData.fDataSize=0;
539       trigData.fData=NULL;
540       size=iOutputDataSize;
541       AliHLTUInt32_t outputBlockCnt=0;
542       AliHLTComponentBlockData* outputBlocks=NULL;
543       AliHLTComponentEventDoneData* edd;
544       if (pTgtBuffer!=NULL || iOutputDataSize==0) {
545         iResult=pComponent->ProcessEvent(evtData, &fBlockDataArray[0], trigData, pTgtBuffer, size, outputBlockCnt, outputBlocks, edd);
546         HLTDebug("task %s: component %s ProcessEvent finnished (%d): size=%d blocks=%d", GetName(), pComponent->GetComponentID(), iResult, size, outputBlockCnt);
547         if (iResult>=0 && outputBlocks) {
548           if (fListTargets.First()!=NULL) {
549             AliHLTComponentBlockDataList segments;
550             for (AliHLTUInt32_t oblock=0; oblock<outputBlockCnt; oblock++) {
551               AliHLTUInt32_t iblock=0;
552               for (; iblock<evtData.fBlockCnt; iblock++) {
553                 if (fBlockDataArray[iblock].fPtr==outputBlocks[oblock].fPtr) {
554                   assert(subscribedTaskList[iblock]!=NULL);
555                   if (subscribedTaskList[iblock]==NULL) continue;
556                   HLTDebug("forward segment %d (source task %s %p) to data buffer %p", iblock, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
557                   fpDataBuffer->Forward(subscribedTaskList[iblock], &fBlockDataArray[iblock]);
558                   subscribedTaskList[iblock]=NULL; // not to be released in the loop further down
559                   break;
560                 }
561               }
562               if (iblock==evtData.fBlockCnt) segments.push_back(outputBlocks[oblock]);
563             }
564             if (pTgtBuffer && segments.size()>0) {
565               iResult=fpDataBuffer->SetSegments(pTgtBuffer, &segments[0], segments.size());
566             }
567           } else {
568             // no forwarding, actually we dont even need to keep the data, this is a
569             // dead end (fListTargets empty)
570             //iResult=fpDataBuffer->SetSegments(pTgtBuffer, outputBlocks, outputBlockCnt);
571           }
572           delete [] outputBlocks; outputBlocks=NULL; outputBlockCnt=0;
573         } else {
574           fpDataBuffer->Reset();
575         }
576         if (fListTargets.First()!=NULL) {
577           if (iSOR>=0 && subscribedTaskList[iSOR]!=NULL) {
578             HLTDebug("forward SOR event segment %d (source task %s %p) to data buffer %p", iSOR, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
579             fpDataBuffer->Forward(subscribedTaskList[iSOR], &fBlockDataArray[iSOR]);
580             subscribedTaskList[iSOR]=NULL; // not to be released in the loop further down
581           }
582           if (iEOR>=0 && subscribedTaskList[iEOR]!=NULL) {
583             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);
584             fpDataBuffer->Forward(subscribedTaskList[iEOR], &fBlockDataArray[iEOR]);
585             subscribedTaskList[iEOR]=NULL; // not to be released in the loop further down
586           }
587         }
588       } else {
589         HLTError("task %s: no target buffer available", GetName());
590         iResult=-EFAULT;
591       }
592     } while (iResult==-ENOSPC && iNofTrial++<1);
593     }
594
595     // now release all buffers which we have subscribed to
596     iSourceDataBlock=0;
597     AliHLTTaskPList::iterator element;
598     while ((element=subscribedTaskList.begin())!=subscribedTaskList.end()) {
599       pSrcTask=*element;
600       if (pSrcTask) {
601         int iTempRes=0;
602         if ((iTempRes=pSrcTask->Release(&fBlockDataArray[iSourceDataBlock], this))>=0) {
603           HLTDebug("Task %s (%p) successfully released segment of task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
604         } else {
605           HLTError("Task %s (%p): realease of task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iTempRes);
606         }
607       }
608       subscribedTaskList.erase(element);
609       iSourceDataBlock++;
610     }
611     if (subscribedTaskList.size()>0) {
612       HLTError("task %s (%p): could not release all data buffers", GetName(), this);
613     }
614   } else {
615     HLTError("task %s (%p): internal failure (not initialized component %p, data buffer %p)", GetName(), this, fpComponent, fpDataBuffer);
616     iResult=-EFAULT;
617   }
618   return iResult;
619 }
620
621 int AliHLTTask::GetNofMatchingDataBlocks(const AliHLTTask* pConsumerTask) const
622 {
623   // see header file for function documentation
624   int iResult=0;
625   if (pConsumerTask) {
626     if (fpDataBuffer) {
627       iResult=fpDataBuffer->FindMatchingDataBlocks(pConsumerTask->GetComponent(), NULL);
628     } else {
629       HLTFatal("internal data buffer missing");
630       iResult=-EFAULT;
631     }
632   } else {
633     iResult=-EINVAL;
634   }
635   return iResult;
636 }
637
638 int AliHLTTask::GetNofMatchingDataTypes(const AliHLTTask* pConsumerTask) const
639 {
640   // see header file for function documentation
641   int iResult=0;
642   if (pConsumerTask) {
643     AliHLTComponent* pComponent=GetComponent();
644     if (!pComponent) {
645       // init ?
646       HLTError("component not initialized");
647       iResult=-EFAULT;
648     }
649     if (pComponent) {
650       iResult=pComponent->FindMatchingDataTypes(pConsumerTask->GetComponent(), NULL);
651     } else {
652       HLTFatal("task initialization failed");
653       iResult=-EFAULT;
654     }
655   } else {
656     iResult=-EINVAL;
657   }
658   return iResult;
659 }
660
661 int AliHLTTask::Subscribe(const AliHLTTask* pConsumerTask, AliHLTComponentBlockDataList& blockDescList)
662 {
663   // see header file for function documentation
664   int iResult=0;
665   if (pConsumerTask) {
666     if (fpDataBuffer) {
667       iResult=fpDataBuffer->Subscribe(pConsumerTask->GetComponent(), blockDescList);
668     } else {
669       HLTFatal("internal data buffer missing");
670       iResult=-EFAULT;
671     }
672   } else {
673     iResult=-EINVAL;
674   }
675   return iResult;
676 }
677
678 int AliHLTTask::Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTTask* pConsumerTask)
679 {
680   // see header file for function documentation
681   int iResult=0;
682   if (pConsumerTask && pBlockDesc) {
683     if (fpDataBuffer) {
684       iResult=fpDataBuffer->Release(pBlockDesc, pConsumerTask->GetComponent(), this);
685     } else {
686       HLTFatal("internal data buffer missing");
687       iResult=-EFAULT;
688     }
689   } else {
690     iResult=-EINVAL;
691   }
692   return iResult;
693 }
694
695 void AliHLTTask::PrintStatus()
696 {
697   // see header file for function documentation
698   HLTLogKeyword("task properties");
699   AliHLTComponent* pComponent=GetComponent();
700   if (pComponent) {
701     HLTMessage("     component: %s (%p)", pComponent->GetComponentID(), pComponent);
702   } else {
703     HLTMessage("     no component set!");
704   }
705   if (fpConfiguration) {
706     AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
707     while (pSrc) {
708       const char* pQualifier="unresolved";
709       if (FindDependency(pSrc->GetName()))
710         pQualifier="resolved";
711       HLTMessage("     source: %s (%s)", pSrc->GetName(), pQualifier);
712       pSrc=fpConfiguration->GetNextSource();
713     }
714     TObjLink* lnk = fListTargets.FirstLink();
715     while (lnk) {
716       TObject *obj = lnk->GetObject();
717       HLTMessage("     target: %s", obj->GetName());
718       lnk = lnk->Next();
719     }
720   } else {
721     HLTMessage("     task \"%s\" not initialized", GetName());
722   }
723 }
724
725 int AliHLTTask::CustomInit(AliHLTComponentHandler* /*pCH*/)
726 {
727   // default implementation nothing to do
728   return 0;
729 }
730
731 int AliHLTTask::CustomCleanup()
732 {
733   // default implementation nothing to do
734   return 0;
735 }