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