]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTConfiguration.cxx
- changes according to coding conventions and documentation
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTConfiguration.cxx
1 // $Id$
2
3 /**************************************************************************
4  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
5  *                                                                        *
6  * Authors: Matthias Richter <Matthias.Richter@ift.uib.no>                *
7  *          for The ALICE Off-line Project.                               *
8  *                                                                        *
9  * Permission to use, copy, modify and distribute this software and its   *
10  * documentation strictly for non-commercial purposes is hereby granted   *
11  * without fee, provided that the above copyright notice appears in all   *
12  * copies and that both the copyright notice and this permission notice   *
13  * appear in the supporting documentation. The authors make no claims     *
14  * about the suitability of this software for any purpose. It is          *
15  * provided "as is" without express or implied warranty.                  *
16  **************************************************************************/
17
18 /** @file   AliHLTConfiguration.cxx
19     @author Matthias Richter
20     @date   
21     @brief  Implementation of HLT configuration handler.
22 */
23
24 #if __GNUC__>= 3
25 using namespace std;
26 #endif
27
28 #include <cerrno>
29 #include "AliHLTConfiguration.h"
30 #include "AliHLTConfigurationHandler.h"
31 #include "AliHLTTask.h"
32 #include "AliHLTComponent.h"
33 #include "AliHLTComponentHandler.h"
34 #include <iostream>
35 #include <string>
36
37 /** ROOT macro for the implementation of ROOT specific class methods */
38 ClassImp(AliHLTConfiguration)
39
40 AliHLTConfiguration::AliHLTConfiguration()
41   :
42   fID(NULL),
43   fComponent(NULL),
44   fStringSources(NULL),
45   fNofSources(-1),
46   fListSources(),
47   fListSrcElement(),
48   fArguments(NULL),
49   fArgc(-1),
50   fArgv(NULL)
51
52   fListSrcElement=fListSources.begin();
53 }
54
55 AliHLTConfiguration::AliHLTConfiguration(const char* id, const char* component, const char* sources, const char* arguments)
56   :
57   fID(id),
58   fComponent(component),
59   fStringSources(sources),
60   fNofSources(-1),
61   fListSources(),
62   fListSrcElement(),
63   fArguments(arguments),
64   fArgc(-1),
65   fArgv(NULL)
66 {
67   fListSrcElement=fListSources.begin();
68   if (id && component) {
69     if (fConfigurationHandler) {
70       fConfigurationHandler->RegisterConfiguration(this);
71     } else {
72       HLTError("no configuration handler set, abort registration");
73     }
74   }
75 }
76
77 AliHLTConfiguration::AliHLTConfiguration(const AliHLTConfiguration&)
78   :
79   TObject(),
80   AliHLTLogging(),
81   fID(NULL),
82   fComponent(NULL),
83   fStringSources(NULL),
84   fNofSources(-1),
85   fListSources(),
86   fListSrcElement(),
87   fArguments(NULL),
88   fArgc(-1),
89   fArgv(NULL)
90
91   fListSrcElement=fListSources.begin();
92   HLTFatal("copy constructor untested");
93 }
94
95 AliHLTConfiguration& AliHLTConfiguration::operator=(const AliHLTConfiguration&)
96
97   HLTFatal("assignment operator untested");
98   return *this;
99 }
100
101 AliHLTConfiguration::~AliHLTConfiguration()
102 {
103   if (fConfigurationHandler) {
104     if (fConfigurationHandler->FindConfiguration(fID)!=NULL) {
105       fConfigurationHandler->RemoveConfiguration(this);
106     }
107   }
108   if (fArgv != NULL) {
109     if (fArgc>0) {
110       for (int i=0; i<fArgc; i++) {
111         delete[] fArgv[i];
112       }
113     }
114     delete[] fArgv;
115     fArgv=NULL;
116   }
117 }
118
119 /* the global configuration handler which is used to automatically register the configuration
120  */
121 AliHLTConfigurationHandler* AliHLTConfiguration::fConfigurationHandler=NULL;
122
123 int AliHLTConfiguration::GlobalInit(AliHLTConfigurationHandler* pHandler)
124 {
125   int iResult=0;
126   if (fConfigurationHandler!=NULL) {
127     fConfigurationHandler->Logging(kHLTLogWarning, "AliHLTConfiguration::GlobalInit", HLT_DEFAULT_LOG_KEYWORD, "configuration handler already initialized, overriding object %p", fConfigurationHandler);
128   }
129   fConfigurationHandler=pHandler;
130   return iResult;
131 }
132
133 int AliHLTConfiguration::GlobalDeinit()
134 {
135   int iResult=0;
136   fConfigurationHandler=NULL;
137   return iResult;
138 }
139
140 const char* AliHLTConfiguration::GetName() const {
141   if (fID)
142     return fID;
143   return TObject::GetName();
144 }
145
146 AliHLTConfiguration* AliHLTConfiguration::GetSource(const char* id)
147 {
148   AliHLTConfiguration* pSrc=NULL;
149   if (id) {
150     // first check the current element
151     if (fListSrcElement!=fListSources.end() && strcmp(id, (*fListSrcElement)->GetName())==0) {
152       pSrc=*fListSrcElement;
153       } else {
154       // check the list
155
156       pSrc=GetFirstSource();
157       while (pSrc) {
158         if (strcmp(id, pSrc->GetName())==0)
159           break;
160         pSrc=GetNextSource();
161       }
162     }
163   }
164   return pSrc;
165 }
166
167 AliHLTConfiguration* AliHLTConfiguration::GetFirstSource()
168 {
169   AliHLTConfiguration* pSrc=NULL;
170   if (fNofSources>=0 || ExtractSources()) {
171     fListSrcElement=fListSources.begin();
172     if (fListSrcElement!=fListSources.end()) pSrc=*fListSrcElement;
173   } 
174   return pSrc;
175 }
176
177 AliHLTConfiguration* AliHLTConfiguration::GetNextSource()
178 {
179   AliHLTConfiguration* pSrc=NULL;
180   if (fNofSources>0) {
181     if (fListSrcElement!=fListSources.end() && (++fListSrcElement)!=fListSources.end()) 
182       pSrc=*fListSrcElement;
183   } 
184   return pSrc;
185 }
186
187 int AliHLTConfiguration::SourcesResolved(int bAuto) 
188 {
189   int iResult=0;
190   if (fNofSources>=0 || bAuto && (iResult=ExtractSources())>=0) {
191     //HLTDebug("fNofSources=%d", fNofSources);
192     //HLTDebug("list size = %d", fListSources.size());
193     iResult=fNofSources==(int)fListSources.size();
194   }
195   return iResult;
196 }
197
198 int AliHLTConfiguration::InvalidateSource(AliHLTConfiguration* pConf)
199 {
200   int iResult=0;
201   if (pConf) {
202     vector<AliHLTConfiguration*>::iterator element=fListSources.begin();
203     while (element!=fListSources.end()) {
204       if (*element==pConf) {
205         fListSources.erase(element);
206         fListSrcElement=fListSources.end();
207         // there is no need to re-evaluate until there was a new configuration registered
208         // -> postpone the invalidation, its done in AliHLTConfigurationHandler::RegisterConfiguration
209         //InvalidateSources();
210         break;
211       }
212       element++;
213     }
214   } else {
215     iResult=-EINVAL;
216   }
217   return iResult;
218 }
219
220 void AliHLTConfiguration::PrintStatus()
221 {
222   HLTLogKeyword("configuration status");
223   HLTMessage("status of configuration \"%s\" (%p)", GetName(), this);
224   if (fComponent) HLTMessage("  - component: \"%s\"", fComponent);
225   else HLTMessage("  - component string invalid");
226   if (fStringSources) HLTMessage("  - sources: \"%s\"", fStringSources);
227   else HLTMessage("  - no sources");
228   if (SourcesResolved(1)<=0)
229     HLTMessage("    there are unresolved sources");
230   AliHLTConfiguration* pSrc=GetFirstSource();
231   while (pSrc) {
232     HLTMessage("    source \"%s\" (%p) resolved", pSrc->GetName(), pSrc);
233     pSrc=GetNextSource();
234   }
235 }
236
237 int AliHLTConfiguration::GetArguments(const char*** pArgv)
238 {
239   int iResult=0;
240   if (pArgv) {
241     iResult=fArgc;
242     *pArgv=(const char**)fArgv;
243   } else {
244     iResult=-EINVAL;
245   }
246   return iResult;
247 }
248
249
250 int AliHLTConfiguration::ExtractSources()
251 {
252   int iResult=0;
253   fNofSources=0;
254   if (fStringSources!=NULL) {
255     vector<char*> tgtList;
256     fListSources.clear();
257     if ((iResult=InterpreteString(fStringSources, tgtList))>=0) {
258       fNofSources=tgtList.size();
259       vector<char*>::iterator element=tgtList.begin();
260       while ((element=tgtList.begin())!=tgtList.end()) {
261         if (fConfigurationHandler) {
262           AliHLTConfiguration* pConf=fConfigurationHandler->FindConfiguration(*element);
263           if (pConf) {
264             HLTDebug("source \"%s\" inserted", pConf->GetName());
265             fListSources.push_back(pConf);
266           } else {
267             HLTError("can not find source \"%s\"", (*element));
268             iResult=-ENOENT;
269           }
270         } else if (iResult>=0) {
271           iResult=-EFAULT;
272           HLTFatal("global configuration handler not initialized, can not resolve sources");
273         }
274         delete[] (*element);
275         tgtList.erase(element);
276       }
277       fListSrcElement=fListSources.begin();
278     }
279   }
280   return iResult;
281 }
282
283 int AliHLTConfiguration::ExtractArguments()
284 {
285   int iResult=0;
286   if (fArguments!=NULL) {
287     vector<char*> tgtList;
288     if ((iResult=InterpreteString(fArguments, tgtList))>=0) {
289       fArgc=tgtList.size();
290       //HLTDebug("found %d arguments", fArgc);
291       if (fArgc>0) {
292         fArgv = new char*[fArgc];
293         if (fArgv) {
294           vector<char*>::iterator element=tgtList.begin();
295           int i=0;
296           while (element!=tgtList.end()) {
297             //HLTDebug("assign arguments %d (%s)", i, *element);
298             fArgv[i++]=(*element);
299             element++;
300           }
301         } else {
302           iResult=-ENOMEM;
303         }
304       }
305     }
306   }
307   return iResult;
308 }
309
310 int AliHLTConfiguration::InterpreteString(const char* arg, vector<char*>& argList)
311 {
312   int iResult=0;
313   if (arg) {
314     //HLTDebug("interprete \"%s\"", arg);
315     int i=0;
316     int prec=-1;
317     do {
318       if (arg[i]==0 || arg[i]==' ') {
319         if (prec>=0) {
320           char* pEntry= new char[i-prec+1];
321           if (pEntry) {
322             strncpy(pEntry, &arg[prec], i-prec);
323             pEntry[i-prec]=0; // terminate string
324             //HLTDebug("create string \"%s\", insert at %d", pEntry, argList.size());
325             argList.push_back(pEntry);
326           } else 
327             iResult=-ENOMEM;
328           prec=-1;
329         }
330       } else if (prec==-1) prec=i;
331     } while (arg[i++]!=0 && iResult>=0); 
332   } else {
333     iResult=-EINVAL;
334   }
335   return iResult;
336 }
337
338 int AliHLTConfiguration::FollowDependency(const char* id, TList* pTgtList)
339 {
340   int iResult=0;
341   if (id) {
342     AliHLTConfiguration* pDep=NULL;
343     if ((pDep=GetSource(id))!=NULL) {
344       if (pTgtList) pTgtList->Add(pDep);
345       iResult++;
346     } else {
347       pDep=GetFirstSource();
348       while (pDep && iResult==0) {
349         if ((iResult=pDep->FollowDependency(id, pTgtList))>0) {
350           if (pTgtList) pTgtList->AddFirst(pDep);
351           iResult++;
352         }
353         pDep=GetNextSource();
354       }
355     }
356   } else {
357     iResult=-EINVAL;
358   }
359   return iResult;
360 }
361
362 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
363
364 /** ROOT macro for the implementation of ROOT specific class methods */
365 ClassImp(AliHLTTask)
366
367 AliHLTTask::AliHLTTask()
368   :
369   fpConfiguration(NULL),
370   fpComponent(NULL),
371   fpDataBuffer(NULL),
372   fListTargets(),
373   fListDependencies(),
374   fpBlockDataArray(NULL),
375   fBlockDataArraySize(0)
376 {
377 }
378
379 AliHLTTask::AliHLTTask(AliHLTConfiguration* pConf)
380   :
381   fpConfiguration(pConf),
382   fpComponent(NULL),
383   fpDataBuffer(NULL),
384   fListTargets(),
385   fListDependencies(),
386   fpBlockDataArray(NULL),
387   fBlockDataArraySize(0)
388 {
389 }
390
391 AliHLTTask::AliHLTTask(const AliHLTTask&)
392   :
393   TObject(),
394   AliHLTLogging(),
395   fpConfiguration(NULL),
396   fpComponent(NULL),
397   fpDataBuffer(NULL),
398   fListTargets(),
399   fListDependencies(),
400   fpBlockDataArray(NULL),
401   fBlockDataArraySize(0)
402 {
403   HLTFatal("copy constructor untested");
404 }
405
406 AliHLTTask& AliHLTTask::operator=(const AliHLTTask&)
407
408   HLTFatal("assignment operator untested");
409   return *this;
410 }
411
412 AliHLTTask::~AliHLTTask()
413 {
414   if (fpComponent) delete fpComponent;
415   fpComponent=NULL;
416   if (fpBlockDataArray) delete[] fpBlockDataArray;
417   fpBlockDataArray=NULL;
418 }
419
420 int AliHLTTask::Init(AliHLTConfiguration* pConf, AliHLTComponentHandler* pCH)
421 {
422   int iResult=0;
423   if (fpConfiguration!=NULL && fpConfiguration!=pConf) {
424     HLTWarning("overriding existing reference to configuration object %p (%s) by %p",
425                fpConfiguration, GetName(), pConf);
426   }
427   if (pConf!=NULL) fpConfiguration=pConf;
428   if (fpConfiguration) {
429     if (pCH) {
430       int argc=0;
431       const char** argv=NULL;
432       if ((iResult=fpConfiguration->GetArguments(&argv))>=0) {
433         argc=iResult; // just to make it clear
434         // TODO: we have to think about the optional environment parameter,
435         // currently just set to NULL. 
436         iResult=pCH->CreateComponent(fpConfiguration->GetComponentID(), NULL, argc, argv, fpComponent);
437         if (fpComponent) {
438         } else {
439           HLTError("can not find component \"%s\"", fpConfiguration->GetComponentID());
440         }
441       }
442     } else {
443       HLTError("component handler instance needed for task initialization");
444       iResult=-EINVAL;
445     }
446   } else {
447     HLTError("configuration object instance needed for task initialization");
448     iResult=-EINVAL;
449   }
450   return iResult;
451 }
452
453 int AliHLTTask::Deinit()
454 {
455   int iResult=0;
456   AliHLTComponent* pComponent=GetComponent();
457   fpComponent=NULL;
458   if (pComponent) {
459     pComponent->Deinit();
460     delete pComponent;
461   } else {
462     HLTWarning("task %s (%p) doesn't seem to be in initialized", GetName(), this);
463   }
464   return iResult;
465 }
466
467 const char *AliHLTTask::GetName() const
468 {
469   if (fpConfiguration)
470     return fpConfiguration->GetName();
471   return TObject::GetName();
472 }
473
474 AliHLTConfiguration* AliHLTTask::GetConf() const
475 {
476   return fpConfiguration;
477 }
478
479 AliHLTComponent* AliHLTTask::GetComponent() const
480 {
481   return fpComponent;
482 }
483
484 AliHLTTask* AliHLTTask::FindDependency(const char* id)
485 {
486   AliHLTTask* pTask=NULL;
487   if (id) {
488     pTask=(AliHLTTask*)fListDependencies.FindObject(id);
489   }
490   return pTask;
491 }
492
493 int AliHLTTask::FollowDependency(const char* id, TList* pTgtList)
494 {
495   int iResult=0;
496   if (id) {
497     AliHLTTask* pDep=NULL;
498     if ((pDep=(AliHLTTask*)fListDependencies.FindObject(id))!=NULL) {
499       if (pTgtList) pTgtList->Add(pDep);
500       iResult++;
501     } else {
502       TObjLink* lnk=fListDependencies.FirstLink();
503       while (lnk && iResult==0) {
504         pDep=(AliHLTTask*)lnk->GetObject();
505         if (pDep) {
506           if ((iResult=pDep->FollowDependency(id, pTgtList))>0) {
507             if (pTgtList) pTgtList->AddFirst(pDep);
508             iResult++;
509           }
510         } else {
511           iResult=-EFAULT;
512         }
513         lnk=lnk->Next();
514       }
515     }
516   } else {
517     iResult=-EINVAL;
518   }
519   return iResult;
520 }
521
522 void AliHLTTask::PrintDependencyTree(const char* id, int bFromConfiguration)
523 {
524   HLTLogKeyword("task dependencies");
525   int iResult=0;
526   TList tgtList;
527   if (bFromConfiguration) {
528     if (fpConfiguration)
529       iResult=fpConfiguration->FollowDependency(id, &tgtList);
530     else
531       iResult=-EFAULT;
532   } else
533     iResult=FollowDependency(id, &tgtList);
534   if (iResult>0) {
535     HLTMessage("     task \"%s\": dependency level %d ", GetName(), iResult);
536     TObjLink* lnk=tgtList.FirstLink();
537     int i=iResult;
538     char* pSpace = new char[iResult+1];
539     if (pSpace) {
540       memset(pSpace, 32, iResult);
541       pSpace[i]=0;
542       while (lnk) {
543         TObject* obj=lnk->GetObject();
544         HLTMessage("     %s^-- %s ", &pSpace[i--], obj->GetName());
545         lnk=lnk->Next();
546       }
547       delete [] pSpace;
548     } else {
549       iResult=-ENOMEM;
550     }
551   }
552 }
553
554 int AliHLTTask::SetDependency(AliHLTTask* pDep)
555 {
556   int iResult=0;
557   if (pDep) {
558     if (FindDependency(pDep->GetName())==NULL) {
559       fListDependencies.Add(pDep);
560     } else {
561       iResult=-EEXIST;
562     }
563   } else {
564     iResult=-EINVAL;
565   }
566   return iResult;
567 }
568
569 int AliHLTTask::CheckDependencies()
570 {
571   int iResult=0;
572   AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
573   while (pSrc) {
574     if (FindDependency(pSrc->GetName())==NULL) {
575       //HLTDebug("dependency \"%s\" unresolved", pSrc->GetName());
576       iResult++;
577     }
578     pSrc=fpConfiguration->GetNextSource();
579   }
580   return iResult;
581 }
582
583
584 int AliHLTTask::Depends(AliHLTTask* pTask)
585 {
586   int iResult=0;
587   if (pTask) {
588     if (fpConfiguration) {
589       iResult=fpConfiguration->GetSource(pTask->GetName())!=NULL;
590       if (iResult>0) {
591         //HLTDebug("task  \"%s\" depends on \"%s\"", GetName(), pTask->GetName());
592       } else {
593         //HLTDebug("task  \"%s\" independend of \"%s\"", GetName(), pTask->GetName());
594       }
595     } else {
596       iResult=-EFAULT;
597     }
598   } else {
599     iResult=-EINVAL;
600   }
601   return iResult;
602 }
603
604 AliHLTTask* AliHLTTask::FindTarget(const char* id)
605 {
606   AliHLTTask* pTask=NULL;
607   if (id) {
608     pTask=(AliHLTTask*)fListTargets.FindObject(id);
609   }
610   return pTask;
611 }
612
613 int AliHLTTask::SetTarget(AliHLTTask* pTgt)
614 {
615   int iResult=0;
616   if (pTgt) {
617     if (FindTarget(pTgt->GetName())==NULL) {
618       fListTargets.Add(pTgt);
619     } else {
620       iResult=-EEXIST;
621     }
622   } else {
623     iResult=-EINVAL;
624   }
625   return iResult;
626 }
627
628 int AliHLTTask::StartRun()
629 {
630   int iResult=0;
631   int iNofInputDataBlocks=0;
632   AliHLTComponent* pComponent=GetComponent();
633   if (pComponent) {
634     // determine the number of input data blocks provided from the source tasks
635     TObjLink* lnk=fListDependencies.FirstLink();
636     while (lnk && iResult>=0) {
637       AliHLTTask* pSrcTask=(AliHLTTask*)lnk->GetObject();
638       if (pSrcTask) {
639         if ((iResult=pSrcTask->GetNofMatchingDataTypes(this))>0) {
640           iNofInputDataBlocks+=iResult;
641         } else if (iResult==0) {
642           HLTWarning("source task %s (%p) does not provide any matching data type for task %s (%p)", pSrcTask->GetName(), pSrcTask, GetName(), this);
643         } else {
644           HLTError("task %s (%p): error getting matching data types for source task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
645           iResult=-EFAULT;
646         }
647       }
648       lnk=lnk->Next();
649     }
650     if (iResult>=0) {
651       if (fpBlockDataArray) {
652         HLTWarning("block data array for task %s (%p) was not cleaned", GetName(), this);
653         delete [] fpBlockDataArray;
654         fpBlockDataArray=NULL;
655         fBlockDataArraySize=0;
656       }
657
658       // component init
659       // the initialization of the component is done by the ComponentHandler after creation
660       // of the component.
661       //iResult=Init( AliHLTComponentEnvironment* environ, void* environ_param, int argc, const char** argv );
662
663       // allocate internal task variables for bookkeeping aso.
664       fpBlockDataArray=new AliHLTComponentBlockData[iNofInputDataBlocks];
665       if (fpBlockDataArray) {
666         fBlockDataArraySize=iNofInputDataBlocks;
667       } else {
668         HLTError("memory allocation failed");
669         iResult=-ENOMEM;
670       }
671     }
672   } else {
673     HLTError("task %s (%p) does not have a component", GetName(), this);
674     iResult=-EFAULT;
675   }
676   return iResult;
677 }
678
679 int AliHLTTask::EndRun()
680 {
681   int iResult=0;
682   if (fpBlockDataArray) {
683     fBlockDataArraySize=0;
684     delete [] fpBlockDataArray;
685     fpBlockDataArray=0;
686   } else {
687     HLTWarning("task %s (%p) doesn't seem to be in running mode", GetName(), this);
688   }
689   return iResult;
690 }
691
692 int AliHLTTask::ProcessTask()
693 {
694   int iResult=0;
695   AliHLTComponent* pComponent=GetComponent();
696   if (pComponent && fpBlockDataArray) {
697     int iSourceDataBlock=0;
698     int iInputDataVolume=0;
699
700     int iNofInputDataBlocks=0;
701     /* TODO: the assumption of only one output data type per component is the current constraint
702      * later it should be checked how many output blocks of the source component match the input
703      * data types of the consumer component (GetNofMatchingDataBlocks). If one assumes that a
704      * certain output block is always been produced, the initialization could be done in the
705      * StartRun. Otherwise the fpBlockDataArray has to be adapted each time.
706      */
707     iNofInputDataBlocks=fListDependencies.GetSize(); // one block per source
708     // is not been used since the allocation was done in StartRun, but check the size
709     if (iNofInputDataBlocks>fBlockDataArraySize) {
710       HLTError("block data array too small");
711     }
712
713     AliHLTTask* pSrcTask=NULL;
714     TList subscribedTaskList;
715     TObjLink* lnk=fListDependencies.FirstLink();
716
717     // subscribe to all source tasks
718     while (lnk && iResult>=0) {
719       pSrcTask=(AliHLTTask*)lnk->GetObject();
720       if (pSrcTask) {
721         if (pSrcTask->GetNofMatchingDataBlocks(this)<fBlockDataArraySize-iSourceDataBlock) {
722           if ((iResult=pSrcTask->Subscribe(this, &fpBlockDataArray[iSourceDataBlock],fBlockDataArraySize-iSourceDataBlock))>0) {
723             for (int i=0; i<iResult; i++) {
724               iInputDataVolume+=fpBlockDataArray[i+iSourceDataBlock].fSize;
725               // put the source task as many times into the list as it provides data blocks
726               // makes the bookkeeping for the data release easier
727               subscribedTaskList.Add(pSrcTask);
728             }
729             iSourceDataBlock+=iResult;
730             HLTDebug("Task %s (%p) successfully subscribed to %d data blocks of task %s (%p)", GetName(), this, iResult, pSrcTask->GetName(), pSrcTask);
731             iResult=0;
732           } else {
733             HLTError("Task %s (%p): subscription to task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iResult);
734             iResult=-EFAULT;
735           }
736         } else {
737           HLTFatal("Task %s (%p): too little space in data block array for subscription to task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
738           iResult=-EFAULT;
739         }
740       } else {
741         HLTFatal("fatal internal error in ROOT list handling");
742         iResult=-EFAULT;
743       }
744       lnk=lnk->Next();
745     }
746
747     // process the event
748     if (iResult>=0) {
749       long unsigned int iConstBase=0;
750       double fInputMultiplier=0;
751       pComponent->GetOutputDataSize(iConstBase, fInputMultiplier);
752       int iOutputDataSize=int(fInputMultiplier*iInputDataVolume) + iConstBase;
753       AliHLTUInt8_t* pTgtBuffer=fpDataBuffer->GetTargetBuffer(iOutputDataSize);
754       AliHLTComponentEventData evtData;
755       AliHLTComponentTriggerData trigData;
756       AliHLTUInt32_t size=iOutputDataSize;
757       AliHLTUInt32_t outputBlockCnt=0;
758       AliHLTComponentBlockData* outputBlocks=NULL;
759       AliHLTComponentEventDoneData* edd;
760       if (pTgtBuffer!=NULL || iOutputDataSize==0) {
761         iResult=pComponent->ProcessEvent(evtData, fpBlockDataArray, trigData, pTgtBuffer, size, outputBlockCnt, outputBlocks, edd);
762         if (iResult>=0) {
763           iResult=fpDataBuffer->SetSegments(pTgtBuffer, outputBlocks, outputBlockCnt);
764         }
765       } else {
766       }
767     }
768
769     // now release all buffers which we have subscribed to
770     iSourceDataBlock=0;
771     lnk=subscribedTaskList.FirstLink();
772     while (lnk) {
773       pSrcTask=(AliHLTTask*)lnk->GetObject();
774       if (pSrcTask) {
775         int iTempRes=0;
776         if ((iTempRes=pSrcTask->Release(&fpBlockDataArray[iSourceDataBlock], this))>=0) {
777           HLTDebug("Task %s (%p) successfully released task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
778         } else {
779           HLTError("Task %s (%p): realease of task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iTempRes);
780         }
781       } else {
782         HLTFatal("internal error in ROOT list handling");
783         if (iResult>=0) iResult=-EFAULT;
784       }
785       subscribedTaskList.Remove(lnk);
786       lnk=subscribedTaskList.FirstLink();
787       iSourceDataBlock++;
788     }
789     if (subscribedTaskList.GetSize()>0) {
790       HLTError("task %s (%p): could not release all data buffers", GetName(), this);
791     }
792   } else {
793     HLTError("internal failure: task not initialized");
794     iResult=-EFAULT;
795   }
796   return iResult;
797 }
798
799 int AliHLTTask::GetNofMatchingDataBlocks(const AliHLTTask* pConsumerTask) const
800 {
801   int iResult=0;
802   if (pConsumerTask) {
803     if (fpDataBuffer) {
804       iResult=fpDataBuffer->FindMatchingDataBlocks(pConsumerTask->GetComponent(), NULL);
805     } else {
806       HLTFatal("internal data buffer missing");
807       iResult=-EFAULT;
808     }
809   } else {
810     iResult=-EINVAL;
811   }
812   return iResult;
813 }
814
815 int AliHLTTask::GetNofMatchingDataTypes(const AliHLTTask* pConsumerTask) const
816 {
817   int iResult=0;
818   if (pConsumerTask) {
819     AliHLTComponent* pComponent=GetComponent();
820     if (!pComponent) {
821       // init
822     }
823     if (pComponent) {
824       iResult=pComponent->FindMatchingDataTypes(pConsumerTask->GetComponent(), NULL);
825     } else {
826       HLTFatal("task initialization failed");
827       iResult=-EFAULT;
828     }
829   } else {
830     iResult=-EINVAL;
831   }
832   return iResult;
833 }
834
835 int AliHLTTask::Subscribe(const AliHLTTask* pConsumerTask, AliHLTComponentBlockData* pBlockDesc, int iArraySize)
836 {
837   int iResult=0;
838   if (pConsumerTask) {
839     if (fpDataBuffer) {
840       iResult=fpDataBuffer->Subscribe(pConsumerTask->GetComponent(), pBlockDesc, iArraySize);
841     } else {
842       HLTFatal("internal data buffer missing");
843       iResult=-EFAULT;
844     }
845   } else {
846     iResult=-EINVAL;
847   }
848   return iResult;
849 }
850
851 int AliHLTTask::Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTTask* pConsumerTask)
852 {
853   int iResult=0;
854   if (pConsumerTask && pBlockDesc) {
855     if (fpDataBuffer) {
856       iResult=fpDataBuffer->Release(pBlockDesc, pConsumerTask->GetComponent());
857     } else {
858       HLTFatal("internal data buffer missing");
859       iResult=-EFAULT;
860     }
861   } else {
862     iResult=-EINVAL;
863   }
864   return iResult;
865 }
866
867 /* this function is most likely depricated
868 int AliHLTTask::ClearSourceBlocks()
869 {
870   int iResult=0;
871   return iResult;
872 }
873 */
874
875 void AliHLTTask::PrintStatus()
876 {
877   HLTLogKeyword("task properties");
878   AliHLTComponent* pComponent=GetComponent();
879   if (pComponent) {
880     HLTMessage("     component: %s (%p)", pComponent->GetComponentID(), pComponent);
881   } else {
882     HLTMessage("     no component set!");
883   }
884   if (fpConfiguration) {
885     AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
886     while (pSrc) {
887       const char* pQualifier="unresolved";
888       if (FindDependency(pSrc->GetName()))
889         pQualifier="resolved";
890       HLTMessage("     source: %s (%s)", pSrc->GetName(), pQualifier);
891       pSrc=fpConfiguration->GetNextSource();
892     }
893     TObjLink* lnk = fListTargets.FirstLink();
894     while (lnk) {
895       TObject *obj = lnk->GetObject();
896       HLTMessage("     target: %s", obj->GetName());
897       lnk = lnk->Next();
898     }
899   } else {
900     HLTMessage("     task \"%s\" not initialized", GetName());
901   }
902 }
903
904 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
905
906 TList AliHLTConfigurationHandler::fListConfigurations;
907 TList AliHLTConfigurationHandler::fListDynamicConfigurations;
908
909 /** ROOT macro for the implementation of ROOT specific class methods */
910 ClassImp(AliHLTConfigurationHandler)
911
912 AliHLTConfigurationHandler::AliHLTConfigurationHandler()
913 {
914 }
915
916 AliHLTConfigurationHandler::~AliHLTConfigurationHandler()
917 {
918   TObjLink* lnk=fListDynamicConfigurations.FirstLink();
919   while (lnk) {
920     TObject* obj=lnk->GetObject();
921     if (fListConfigurations.FindObject(obj->GetName())==NULL) {
922       HLTDebug("delete dynamic configuration \"%s\"", obj->GetName());
923       delete obj;
924     }
925     lnk=lnk->Next();
926   }
927 }
928
929 int AliHLTConfigurationHandler::RegisterConfiguration(AliHLTConfiguration* pConf)
930 {
931   int iResult=0;
932   if (pConf) {
933     if (FindConfiguration(pConf->GetName()) == NULL) {
934       fListConfigurations.Add(pConf);
935       //HLTDebug("configuration \"%s\" registered", pConf->GetName());
936
937       // mark all configurations with unresolved dependencies for re-evaluation
938       TObjLink* lnk=fListConfigurations.FirstLink();
939       while (lnk) {
940         AliHLTConfiguration* pSrc=(AliHLTConfiguration*)lnk->GetObject();
941         if (pSrc && pSrc!=pConf && pSrc->SourcesResolved()!=1) {
942           pSrc->InvalidateSources();
943         }
944         lnk=lnk->Next();
945       }
946     } else {
947       iResult=-EEXIST;
948       HLTWarning("configuration \"%s\" already registered", pConf->GetName());
949     }
950   } else {
951     iResult=-EINVAL;
952   }
953   return iResult;
954 }
955
956 int AliHLTConfigurationHandler::CreateConfiguration(const char* id, const char* component, const char* sources, const char* arguments)
957 {
958   int iResult=0;
959   AliHLTConfiguration* pConf= new AliHLTConfiguration(id, component, sources, arguments);
960   if (pConf) {
961     // the configuration will be registered automatically, if this failes the configuration
962     // is missing -> delete it
963     if (FindConfiguration(id)==NULL) {
964       delete pConf;
965       pConf=NULL;
966       iResult=-EEXIST;
967     } else {
968       fListDynamicConfigurations.Add(pConf);
969     }
970   } else {
971     HLTError("system error: object allocation failed");
972     iResult=-ENOMEM;
973   }
974   return iResult;
975 }
976
977 void AliHLTConfigurationHandler::PrintConfigurations()
978 {
979   HLTLogKeyword("configuration listing");
980   HLTMessage("registered configurations:");
981   TObjLink *lnk = fListConfigurations.FirstLink();
982   while (lnk) {
983     TObject *obj = lnk->GetObject();
984     HLTMessage("  %s", obj->GetName());
985     lnk = lnk->Next();
986   }
987 }
988
989 int AliHLTConfigurationHandler::RemoveConfiguration(const char* id)
990 {
991   int iResult=0;
992   if (id) {
993     AliHLTConfiguration* pConf=NULL;
994     if ((pConf=FindConfiguration(id))!=NULL) {
995       iResult=RemoveConfiguration(pConf);
996     } else {
997       HLTWarning("can not find configuration \"%s\"", id);
998       iResult=-ENOENT;
999     }
1000   } else {
1001     iResult=-EINVAL;
1002   }
1003   return iResult;
1004 }
1005
1006 int AliHLTConfigurationHandler::RemoveConfiguration(AliHLTConfiguration* pConf)
1007 {
1008   int iResult=0;
1009   if (pConf) {
1010     // remove the configuration from the list
1011     fListConfigurations.Remove(pConf);
1012     // remove cross links in the remaining configurations
1013     TObjLink* lnk=fListConfigurations.FirstLink();
1014     while (lnk && iResult>=0) {
1015       AliHLTConfiguration* pRem=(AliHLTConfiguration*)lnk->GetObject();
1016       if (pRem) {
1017         pRem->InvalidateSource(pConf);
1018       } else {
1019         iResult=-EFAULT;
1020       }
1021       lnk=lnk->Next();
1022     }
1023   }
1024   return iResult;
1025 }
1026
1027 AliHLTConfiguration* AliHLTConfigurationHandler::FindConfiguration(const char* id)
1028 {
1029   AliHLTConfiguration* pConf=NULL;
1030   if (id) {
1031     pConf=(AliHLTConfiguration*)fListConfigurations.FindObject(id); 
1032   }
1033   return pConf;
1034 }
1035