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