]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTConfiguration.cxx
9fe5c1960b33ca7450197a4c07629866d318cb98
[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 previous 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         iResult=pCH->CreateComponent(fpConfiguration->GetComponentID(), NULL, argc, argv, fpComponent);
435         if (fpComponent) {
436         } else {
437           HLTError("can not find component \"%s\"", fpConfiguration->GetComponentID());
438         }
439       }
440     } else {
441       HLTError("component handler instance needed for task initialization");
442       iResult=-EINVAL;
443     }
444   } else {
445     HLTError("configuration object instance needed for task initialization");
446     iResult=-EINVAL;
447   }
448   return iResult;
449 }
450
451 int AliHLTTask::Deinit()
452 {
453   return 0;
454 }
455
456 const char *AliHLTTask::GetName() const
457 {
458   if (fpConfiguration)
459     return fpConfiguration->GetName();
460   return TObject::GetName();
461 }
462
463 AliHLTConfiguration* AliHLTTask::GetConf() const
464 {
465   return fpConfiguration;
466 }
467
468 AliHLTComponent* AliHLTTask::GetComponent() const
469 {
470   return fpComponent;
471 }
472
473 AliHLTTask* AliHLTTask::FindDependency(const char* id)
474 {
475   AliHLTTask* pTask=NULL;
476   if (id) {
477     pTask=(AliHLTTask*)fListDependencies.FindObject(id);
478   }
479   return pTask;
480 }
481
482 int AliHLTTask::FollowDependency(const char* id, TList* pTgtList)
483 {
484   int iResult=0;
485   if (id) {
486     AliHLTTask* pDep=NULL;
487     if ((pDep=(AliHLTTask*)fListDependencies.FindObject(id))!=NULL) {
488       if (pTgtList) pTgtList->Add(pDep);
489       iResult++;
490     } else {
491       TObjLink* lnk=fListDependencies.FirstLink();
492       while (lnk && iResult==0) {
493         pDep=(AliHLTTask*)lnk->GetObject();
494         if (pDep) {
495           if ((iResult=pDep->FollowDependency(id, pTgtList))>0) {
496             if (pTgtList) pTgtList->AddFirst(pDep);
497             iResult++;
498           }
499         } else {
500           iResult=-EFAULT;
501         }
502         lnk=lnk->Next();
503       }
504     }
505   } else {
506     iResult=-EINVAL;
507   }
508   return iResult;
509 }
510
511 void AliHLTTask::PrintDependencyTree(const char* id, int bFromConfiguration)
512 {
513   HLTLogKeyword("task dependencies");
514   int iResult=0;
515   TList tgtList;
516   if (bFromConfiguration) {
517     if (fpConfiguration)
518       iResult=fpConfiguration->FollowDependency(id, &tgtList);
519     else
520       iResult=-EFAULT;
521   } else
522     iResult=FollowDependency(id, &tgtList);
523   if (iResult>0) {
524     HLTMessage("     task \"%s\": dependency level %d ", GetName(), iResult);
525     TObjLink* lnk=tgtList.FirstLink();
526     int i=iResult;
527     char* pSpace = new char[iResult+1];
528     if (pSpace) {
529       memset(pSpace, 32, iResult);
530       pSpace[i]=0;
531       while (lnk) {
532         TObject* obj=lnk->GetObject();
533         HLTMessage("     %s^-- %s ", &pSpace[i--], obj->GetName());
534         lnk=lnk->Next();
535       }
536       delete [] pSpace;
537     } else {
538       iResult=-ENOMEM;
539     }
540   }
541 }
542
543 /* this function is most likely depricated
544 int AliHLTTask::InsertBlockData(AliHLTComponentBlockData* pBlock, AliHLTTask* pSource)
545 {
546   int iResult=0;
547   return iResult;
548 }
549 */
550
551 int AliHLTTask::SetDependency(AliHLTTask* pDep)
552 {
553   int iResult=0;
554   if (pDep) {
555     if (FindDependency(pDep->GetName())==NULL) {
556       fListDependencies.Add(pDep);
557     } else {
558       iResult=-EEXIST;
559     }
560   } else {
561     iResult=-EINVAL;
562   }
563   return iResult;
564 }
565
566 int AliHLTTask::CheckDependencies()
567 {
568   int iResult=0;
569   AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
570   while (pSrc) {
571     if (FindDependency(pSrc->GetName())==NULL) {
572       //HLTDebug("dependency \"%s\" unresolved", pSrc->GetName());
573       iResult++;
574     }
575     pSrc=fpConfiguration->GetNextSource();
576   }
577   return iResult;
578 }
579
580
581 int AliHLTTask::Depends(AliHLTTask* pTask)
582 {
583   int iResult=0;
584   if (pTask) {
585     if (fpConfiguration) {
586       iResult=fpConfiguration->GetSource(pTask->GetName())!=NULL;
587       if (iResult>0) {
588         //HLTDebug("task  \"%s\" depends on \"%s\"", GetName(), pTask->GetName());
589       } else {
590         //HLTDebug("task  \"%s\" independend of \"%s\"", GetName(), pTask->GetName());
591       }
592     } else {
593       iResult=-EFAULT;
594     }
595   } else {
596     iResult=-EINVAL;
597   }
598   return iResult;
599 }
600
601 AliHLTTask* AliHLTTask::FindTarget(const char* id)
602 {
603   AliHLTTask* pTask=NULL;
604   if (id) {
605     pTask=(AliHLTTask*)fListTargets.FindObject(id);
606   }
607   return pTask;
608 }
609
610 int AliHLTTask::SetTarget(AliHLTTask* pTgt)
611 {
612   int iResult=0;
613   if (pTgt) {
614     if (FindTarget(pTgt->GetName())==NULL) {
615       fListTargets.Add(pTgt);
616     } else {
617       iResult=-EEXIST;
618     }
619   } else {
620     iResult=-EINVAL;
621   }
622   return iResult;
623 }
624
625 /* this function is most likely depricated
626 int AliHLTTask::BuildBlockDataArray(AliHLTComponentBlockData*& pBlockData)
627 {
628   int iResult=0;
629   return iResult;
630 }
631 */
632
633 int AliHLTTask::StartRun()
634 {
635   int iResult=0;
636   int iNofInputDataBlocks=0;
637   AliHLTComponent* pComponent=GetComponent();
638   if (pComponent) {
639     // determine the number of input data blocks provided from the source tasks
640     TObjLink* lnk=fListDependencies.FirstLink();
641     while (lnk && iResult>=0) {
642       AliHLTTask* pSrcTask=(AliHLTTask*)lnk->GetObject();
643       if (pSrcTask) {
644         if ((iResult=pSrcTask->GetNofMatchingDataTypes(this))>0) {
645           iNofInputDataBlocks+=iResult;
646         } else if (iResult==0) {
647           HLTWarning("source task %s (%p) does not provide any matching data type for task %s (%p)", pSrcTask->GetName(), pSrcTask, GetName(), this);
648         } else {
649           HLTError("task %s (%p): error getting matching data types for source task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
650           iResult=-EFAULT;
651         }
652       }
653       lnk=lnk->Next();
654     }
655     if (iResult>=0) {
656       if (fpBlockDataArray) {
657         HLTWarning("block data array for task %s (%p) was not cleaned", GetName(), this);
658         delete [] fpBlockDataArray;
659         fpBlockDataArray=NULL;
660         fBlockDataArraySize=0;
661       }
662
663       // component init
664       //iResult=Init( AliHLTComponentEnvironment* environ, void* environ_param, int argc, const char** argv );
665
666       // allocate internal task varables for bookkeeping aso.
667       fpBlockDataArray=new AliHLTComponentBlockData[iNofInputDataBlocks];
668       if (fpBlockDataArray) {
669         fBlockDataArraySize=iNofInputDataBlocks;
670       } else {
671         HLTError("memory allocation failed");
672         iResult=-ENOMEM;
673       }
674     }
675   } else {
676     HLTError("task %s (%p) does not have a component", GetName(), this);
677     iResult=-EFAULT;
678   }
679   return iResult;
680 }
681
682 int AliHLTTask::EndRun()
683 {
684   int iResult=0;
685   return iResult;
686 }
687
688 int AliHLTTask::ProcessTask()
689 {
690   int iResult=0;
691   if (fpComponent && fpBlockDataArray) {
692     int iSourceDataBlock=0;
693     int iInputDataVolume=0;
694
695     int iNofInputDataBlocks=0;
696     /* TODO: the assumption of only one output data type per component is the current constraint
697      * later it should be checked how many output blocks of the source component match the input
698      * data types of the consumer component (GetNofMatchingDataBlocks). If one assumes that a
699      * certain output block is always been produced, the initialization could be done in the
700      * StartRun. Otherwise the fpBlockDataArray has to be adapted each time.
701      */
702     iNofInputDataBlocks=fListDependencies.GetSize(); // one block per source
703     // is not been used since the allocation was done in StartRun, but check the size
704     if (iNofInputDataBlocks>fBlockDataArraySize) {
705       HLTError("block data array too small");
706     }
707
708     AliHLTTask* pSrcTask=NULL;
709     TList subscribedTaskList;
710     TObjLink* lnk=fListDependencies.FirstLink();
711
712     // subscribe to all source tasks
713     while (lnk && iResult>=0) {
714       pSrcTask=(AliHLTTask*)lnk->GetObject();
715       if (pSrcTask) {
716         if (pSrcTask->GetNofMatchingDataBlocks(this)<fBlockDataArraySize-iSourceDataBlock) {
717           if ((iResult=pSrcTask->Subscribe(this, &fpBlockDataArray[iSourceDataBlock],fBlockDataArraySize-iSourceDataBlock))>0) {
718             for (int i=0; i<iResult; i++) {
719               iInputDataVolume+=fpBlockDataArray[i+iSourceDataBlock].fSize;
720               // put the source task as many times into the list as it provides data blocks
721               // makes the bookkeeping for the data release easier
722               subscribedTaskList.Add(pSrcTask);
723             }
724             iSourceDataBlock+=iResult;
725             HLTDebug("Task %s (%p) successfully subscribed to %d data blocks of task %s (%p)", GetName(), this, iResult, pSrcTask->GetName(), pSrcTask);
726             iResult=0;
727           } else {
728             HLTError("Task %s (%p): subscription to task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iResult);
729             iResult=-EFAULT;
730           }
731         } else {
732           HLTFatal("Task %s (%p): too little space in data block array for subscription to task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
733           iResult=-EFAULT;
734         }
735       } else {
736         HLTFatal("fatal internal error in ROOT list handling");
737         iResult=-EFAULT;
738       }
739       lnk=lnk->Next();
740     }
741
742     // process the event
743     if (iResult>=0) {
744       long unsigned int iConstBase=0;
745       double fInputMultiplier=0;
746       fpComponent->GetOutputDataSize(iConstBase, fInputMultiplier);
747       int iOutputDataSize=int(fInputMultiplier*iInputDataVolume) + iConstBase;
748       AliHLTUInt8_t* pTgtBuffer=fpDataBuffer->GetTargetBuffer(iOutputDataSize);
749       AliHLTComponentEventData evtData;
750       AliHLTComponentTriggerData trigData;
751       AliHLTUInt32_t size=iOutputDataSize;
752       AliHLTUInt32_t outputBlockCnt=0;
753       AliHLTComponentBlockData* outputBlocks=NULL;
754       AliHLTComponentEventDoneData* edd;
755       if (pTgtBuffer!=NULL || iOutputDataSize==0) {
756         iResult=fpComponent->ProcessEvent(evtData, fpBlockDataArray, trigData, pTgtBuffer, size, outputBlockCnt, outputBlocks, edd);
757       } else {
758       }
759     }
760
761     // now release all buffers which we have subscribed to
762     iSourceDataBlock=0;
763     lnk=subscribedTaskList.FirstLink();
764     while (lnk) {
765       pSrcTask=(AliHLTTask*)lnk->GetObject();
766       if (pSrcTask) {
767         int iTempRes=0;
768         if ((iTempRes=pSrcTask->Release(&fpBlockDataArray[iSourceDataBlock], this))>=0) {
769           HLTDebug("Task %s (%p) successfully released task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
770         } else {
771           HLTError("Task %s (%p): realease of task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iTempRes);
772         }
773       } else {
774         HLTFatal("fatal internal error in ROOT list handling");
775         iResult=-EFAULT;
776       }
777       subscribedTaskList.Remove(lnk);
778       lnk=subscribedTaskList.FirstLink();
779       iSourceDataBlock++;
780     }
781     if (subscribedTaskList.GetSize()>0) {
782       HLTError("task %s (%p): could not release all data buffers", GetName(), this);
783     }
784   } else {
785     HLTError("internal failure: task not initialized");
786     iResult=-EFAULT;
787   }
788   return iResult;
789 }
790
791 int AliHLTTask::GetNofMatchingDataBlocks(const AliHLTTask* pConsumerTask)
792 {
793   int iResult=0;
794   if (pConsumerTask) {
795     if (fpDataBuffer) {
796       iResult=fpDataBuffer->FindMatchingDataBlocks(pConsumerTask->GetComponent(), NULL);
797     } else {
798       HLTFatal("internal data buffer missing");
799       iResult=-EFAULT;
800     }
801   } else {
802     iResult=-EINVAL;
803   }
804   return iResult;
805 }
806
807 int AliHLTTask::GetNofMatchingDataTypes(const AliHLTTask* pConsumerTask)
808 {
809   int iResult=0;
810   if (pConsumerTask) {
811     AliHLTComponent* pComponent=GetComponent();
812     if (!pComponent) {
813       // init
814     }
815     if (pComponent) {
816       iResult=pComponent->FindMatchingDataTypes(pConsumerTask->GetComponent(), NULL);
817     } else {
818       HLTFatal("task initialization failed");
819       iResult=-EFAULT;
820     }
821   } else {
822     iResult=-EINVAL;
823   }
824   return iResult;
825 }
826
827 int AliHLTTask::Subscribe(const AliHLTTask* pConsumerTask, AliHLTComponentBlockData* pBlockDesc, int iArraySize)
828 {
829   int iResult=0;
830   if (pConsumerTask) {
831     if (fpDataBuffer) {
832       iResult=fpDataBuffer->Subscribe(pConsumerTask->GetComponent(), pBlockDesc, iArraySize);
833     } else {
834       HLTFatal("internal data buffer missing");
835       iResult=-EFAULT;
836     }
837   } else {
838     iResult=-EINVAL;
839   }
840   return iResult;
841 }
842
843 int AliHLTTask::Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTTask* pConsumerTask)
844 {
845   int iResult=0;
846   if (pConsumerTask && pBlockDesc) {
847     if (fpDataBuffer) {
848       iResult=fpDataBuffer->Release(pBlockDesc, pConsumerTask->GetComponent());
849     } else {
850       HLTFatal("internal data buffer missing");
851       iResult=-EFAULT;
852     }
853   } else {
854     iResult=-EINVAL;
855   }
856   return iResult;
857 }
858
859 /* this function is most likely depricated
860 int AliHLTTask::ClearSourceBlocks()
861 {
862   int iResult=0;
863   return iResult;
864 }
865 */
866
867 void AliHLTTask::PrintStatus()
868 {
869   HLTLogKeyword("task properties");
870   if (fpComponent) {
871     HLTMessage("     component: %s (%p)", fpComponent->GetComponentID(), fpComponent);
872   } else {
873     HLTMessage("     no component set!");
874   }
875   if (fpConfiguration) {
876     AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
877     while (pSrc) {
878       const char* pQualifier="unresolved";
879       if (FindDependency(pSrc->GetName()))
880         pQualifier="resolved";
881       HLTMessage("     source: %s (%s)", pSrc->GetName(), pQualifier);
882       pSrc=fpConfiguration->GetNextSource();
883     }
884     TObjLink* lnk = fListTargets.FirstLink();
885     while (lnk) {
886       TObject *obj = lnk->GetObject();
887       HLTMessage("     target: %s", obj->GetName());
888       lnk = lnk->Next();
889     }
890   } else {
891     HLTMessage("     task \"%s\" not initialized", GetName());
892   }
893 }
894
895 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
896
897 TList AliHLTConfigurationHandler::fListConfigurations;
898 TList AliHLTConfigurationHandler::fListDynamicConfigurations;
899
900 /** ROOT macro for the implementation of ROOT specific class methods */
901 ClassImp(AliHLTConfigurationHandler)
902
903 AliHLTConfigurationHandler::AliHLTConfigurationHandler()
904 {
905 }
906
907 AliHLTConfigurationHandler::~AliHLTConfigurationHandler()
908 {
909   TObjLink* lnk=fListDynamicConfigurations.FirstLink();
910   while (lnk) {
911     TObject* obj=lnk->GetObject();
912     if (fListConfigurations.FindObject(obj->GetName())==NULL) {
913       HLTDebug("delete dynamic configuration \"%s\"", obj->GetName());
914       delete obj;
915     }
916     lnk=lnk->Next();
917   }
918 }
919
920 int AliHLTConfigurationHandler::RegisterConfiguration(AliHLTConfiguration* pConf)
921 {
922   int iResult=0;
923   if (pConf) {
924     if (FindConfiguration(pConf->GetName()) == NULL) {
925       fListConfigurations.Add(pConf);
926       //HLTDebug("configuration \"%s\" registered", pConf->GetName());
927
928       // mark all configurations with unresolved dependencies for re-evaluation
929       TObjLink* lnk=fListConfigurations.FirstLink();
930       while (lnk) {
931         AliHLTConfiguration* pSrc=(AliHLTConfiguration*)lnk->GetObject();
932         if (pSrc && pSrc!=pConf && pSrc->SourcesResolved()!=1) {
933           pSrc->InvalidateSources();
934         }
935         lnk=lnk->Next();
936       }
937     } else {
938       iResult=-EEXIST;
939       HLTWarning("configuration \"%s\" already registered", pConf->GetName());
940     }
941   } else {
942     iResult=-EINVAL;
943   }
944   return iResult;
945 }
946
947 int AliHLTConfigurationHandler::CreateConfiguration(const char* id, const char* component, const char* sources, const char* arguments)
948 {
949   int iResult=0;
950   AliHLTConfiguration* pConf= new AliHLTConfiguration(id, component, sources, arguments);
951   if (pConf) {
952     // the configuration will be registered automatically, if this failes the configuration
953     // is missing -> delete it
954     if (FindConfiguration(id)==NULL) {
955       delete pConf;
956       pConf=NULL;
957       iResult=-EEXIST;
958     } else {
959       fListDynamicConfigurations.Add(pConf);
960     }
961   } else {
962     HLTError("system error: object allocation failed");
963     iResult=-ENOMEM;
964   }
965   return iResult;
966 }
967
968 void AliHLTConfigurationHandler::PrintConfigurations()
969 {
970   HLTLogKeyword("configuration listing");
971   HLTMessage("registered configurations:");
972   TObjLink *lnk = fListConfigurations.FirstLink();
973   while (lnk) {
974     TObject *obj = lnk->GetObject();
975     HLTMessage("  %s", obj->GetName());
976     lnk = lnk->Next();
977   }
978 }
979
980 int AliHLTConfigurationHandler::RemoveConfiguration(const char* id)
981 {
982   int iResult=0;
983   if (id) {
984     AliHLTConfiguration* pConf=NULL;
985     if ((pConf=FindConfiguration(id))!=NULL) {
986       iResult=RemoveConfiguration(pConf);
987     } else {
988       HLTWarning("can not find configuration \"%s\"", id);
989       iResult=-ENOENT;
990     }
991   } else {
992     iResult=-EINVAL;
993   }
994   return iResult;
995 }
996
997 int AliHLTConfigurationHandler::RemoveConfiguration(AliHLTConfiguration* pConf)
998 {
999   int iResult=0;
1000   if (pConf) {
1001     // remove the configuration from the list
1002     fListConfigurations.Remove(pConf);
1003     // remove cross links in the remaining configurations
1004     TObjLink* lnk=fListConfigurations.FirstLink();
1005     while (lnk && iResult>=0) {
1006       AliHLTConfiguration* pRem=(AliHLTConfiguration*)lnk->GetObject();
1007       if (pRem) {
1008         pRem->InvalidateSource(pConf);
1009       } else {
1010         iResult=-EFAULT;
1011       }
1012       lnk=lnk->Next();
1013     }
1014   }
1015   return iResult;
1016 }
1017
1018 AliHLTConfiguration* AliHLTConfigurationHandler::FindConfiguration(const char* id)
1019 {
1020   AliHLTConfiguration* pConf=NULL;
1021   if (id) {
1022     pConf=(AliHLTConfiguration*)fListConfigurations.FindObject(id); 
1023   }
1024   return pConf;
1025 }
1026