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