Implementation of kChain HLTOUT handler
[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       size=iOutputDataSize;
538       AliHLTUInt32_t outputBlockCnt=0;
539       AliHLTComponentBlockData* outputBlocks=NULL;
540       AliHLTComponentEventDoneData* edd;
541       if (pTgtBuffer!=NULL || iOutputDataSize==0) {
542         iResult=pComponent->ProcessEvent(evtData, &fBlockDataArray[0], trigData, pTgtBuffer, size, outputBlockCnt, outputBlocks, edd);
543         HLTDebug("task %s: component %s ProcessEvent finnished (%d): size=%d blocks=%d", GetName(), pComponent->GetComponentID(), iResult, size, outputBlockCnt);
544         if (iResult>=0 && outputBlocks) {
545           if (fListTargets.First()!=NULL) {
546             AliHLTComponentBlockDataList segments;
547             for (AliHLTUInt32_t oblock=0; oblock<outputBlockCnt; oblock++) {
548               AliHLTUInt32_t iblock=0;
549               for (; iblock<evtData.fBlockCnt; iblock++) {
550                 if (fBlockDataArray[iblock].fPtr==outputBlocks[oblock].fPtr) {
551                   assert(subscribedTaskList[iblock]!=NULL);
552                   if (subscribedTaskList[iblock]==NULL) continue;
553                   HLTDebug("forward segment %d (source task %s %p) to data buffer %p", iblock, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
554                   fpDataBuffer->Forward(subscribedTaskList[iblock], &fBlockDataArray[iblock]);
555                   subscribedTaskList[iblock]=NULL; // not to be released in the loop further down
556                   break;
557                 }
558               }
559               if (iblock==evtData.fBlockCnt) segments.push_back(outputBlocks[oblock]);
560             }
561             if (pTgtBuffer && segments.size()>0) {
562               iResult=fpDataBuffer->SetSegments(pTgtBuffer, &segments[0], segments.size());
563             }
564           } else {
565             // no forwarding, actually we dont even need to keep the data, this is a
566             // dead end (fListTargets empty)
567             //iResult=fpDataBuffer->SetSegments(pTgtBuffer, outputBlocks, outputBlockCnt);
568           }
569           delete [] outputBlocks; outputBlocks=NULL; outputBlockCnt=0;
570         } else {
571           fpDataBuffer->Reset();
572         }
573         if (fListTargets.First()!=NULL) {
574           if (iSOR>=0 && subscribedTaskList[iSOR]!=NULL) {
575             HLTDebug("forward SOR event segment %d (source task %s %p) to data buffer %p", iSOR, pSrcTask->GetName(), pSrcTask, fpDataBuffer);
576             fpDataBuffer->Forward(subscribedTaskList[iSOR], &fBlockDataArray[iSOR]);
577             subscribedTaskList[iSOR]=NULL; // not to be released in the loop further down
578           }
579           if (iEOR>=0 && subscribedTaskList[iEOR]!=NULL) {
580             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);
581             fpDataBuffer->Forward(subscribedTaskList[iEOR], &fBlockDataArray[iEOR]);
582             subscribedTaskList[iEOR]=NULL; // not to be released in the loop further down
583           }
584         }
585       } else {
586         HLTError("task %s: no target buffer available", GetName());
587         iResult=-EFAULT;
588       }
589     } while (iResult==-ENOSPC && iNofTrial++<1);
590     }
591
592     // now release all buffers which we have subscribed to
593     iSourceDataBlock=0;
594     AliHLTTaskPList::iterator element;
595     while ((element=subscribedTaskList.begin())!=subscribedTaskList.end()) {
596       pSrcTask=*element;
597       if (pSrcTask) {
598         int iTempRes=0;
599         if ((iTempRes=pSrcTask->Release(&fBlockDataArray[iSourceDataBlock], this))>=0) {
600           HLTDebug("Task %s (%p) successfully released segment of task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
601         } else {
602           HLTError("Task %s (%p): realease of task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iTempRes);
603         }
604       }
605       subscribedTaskList.erase(element);
606       iSourceDataBlock++;
607     }
608     if (subscribedTaskList.size()>0) {
609       HLTError("task %s (%p): could not release all data buffers", GetName(), this);
610     }
611   } else {
612     HLTError("task %s (%p): internal failure (not initialized component %p, data buffer %p)", GetName(), this, fpComponent, fpDataBuffer);
613     iResult=-EFAULT;
614   }
615   return iResult;
616 }
617
618 int AliHLTTask::GetNofMatchingDataBlocks(const AliHLTTask* pConsumerTask) const
619 {
620   // see header file for function documentation
621   int iResult=0;
622   if (pConsumerTask) {
623     if (fpDataBuffer) {
624       iResult=fpDataBuffer->FindMatchingDataBlocks(pConsumerTask->GetComponent(), NULL);
625     } else {
626       HLTFatal("internal data buffer missing");
627       iResult=-EFAULT;
628     }
629   } else {
630     iResult=-EINVAL;
631   }
632   return iResult;
633 }
634
635 int AliHLTTask::GetNofMatchingDataTypes(const AliHLTTask* pConsumerTask) const
636 {
637   // see header file for function documentation
638   int iResult=0;
639   if (pConsumerTask) {
640     AliHLTComponent* pComponent=GetComponent();
641     if (!pComponent) {
642       // init ?
643       HLTError("component not initialized");
644       iResult=-EFAULT;
645     }
646     if (pComponent) {
647       iResult=pComponent->FindMatchingDataTypes(pConsumerTask->GetComponent(), NULL);
648     } else {
649       HLTFatal("task initialization failed");
650       iResult=-EFAULT;
651     }
652   } else {
653     iResult=-EINVAL;
654   }
655   return iResult;
656 }
657
658 int AliHLTTask::Subscribe(const AliHLTTask* pConsumerTask, AliHLTComponentBlockDataList& blockDescList)
659 {
660   // see header file for function documentation
661   int iResult=0;
662   if (pConsumerTask) {
663     if (fpDataBuffer) {
664       iResult=fpDataBuffer->Subscribe(pConsumerTask->GetComponent(), blockDescList);
665     } else {
666       HLTFatal("internal data buffer missing");
667       iResult=-EFAULT;
668     }
669   } else {
670     iResult=-EINVAL;
671   }
672   return iResult;
673 }
674
675 int AliHLTTask::Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTTask* pConsumerTask)
676 {
677   // see header file for function documentation
678   int iResult=0;
679   if (pConsumerTask && pBlockDesc) {
680     if (fpDataBuffer) {
681       iResult=fpDataBuffer->Release(pBlockDesc, pConsumerTask->GetComponent(), this);
682     } else {
683       HLTFatal("internal data buffer missing");
684       iResult=-EFAULT;
685     }
686   } else {
687     iResult=-EINVAL;
688   }
689   return iResult;
690 }
691
692 void AliHLTTask::PrintStatus()
693 {
694   // see header file for function documentation
695   HLTLogKeyword("task properties");
696   AliHLTComponent* pComponent=GetComponent();
697   if (pComponent) {
698     HLTMessage("     component: %s (%p)", pComponent->GetComponentID(), pComponent);
699   } else {
700     HLTMessage("     no component set!");
701   }
702   if (fpConfiguration) {
703     AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
704     while (pSrc) {
705       const char* pQualifier="unresolved";
706       if (FindDependency(pSrc->GetName()))
707         pQualifier="resolved";
708       HLTMessage("     source: %s (%s)", pSrc->GetName(), pQualifier);
709       pSrc=fpConfiguration->GetNextSource();
710     }
711     TObjLink* lnk = fListTargets.FirstLink();
712     while (lnk) {
713       TObject *obj = lnk->GetObject();
714       HLTMessage("     target: %s", obj->GetName());
715       lnk = lnk->Next();
716     }
717   } else {
718     HLTMessage("     task \"%s\" not initialized", GetName());
719   }
720 }
721
722 int AliHLTTask::CustomInit(AliHLTComponentHandler* /*pCH*/)
723 {
724   // default implementation nothing to do
725   return 0;
726 }
727
728 int AliHLTTask::CustomCleanup()
729 {
730   // default implementation nothing to do
731   return 0;
732 }