3 /**************************************************************************
4 * This file is property of and copyright by the ALICE HLT Project *
5 * ALICE Experiment at CERN, All rights reserved. *
7 * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 * Timm Steinbeck <timm@kip.uni-heidelberg.de> *
9 * for The ALICE HLT Project. *
11 * Permission to use, copy, modify and distribute this software and its *
12 * documentation strictly for non-commercial purposes is hereby granted *
13 * without fee, provided that the above copyright notice appears in all *
14 * copies and that both the copyright notice and this permission notice *
15 * appear in the supporting documentation. The authors make no claims *
16 * about the suitability of this software for any purpose. It is *
17 * provided "as is" without express or implied warranty. *
18 **************************************************************************/
20 /** @file AliHLTComponentHandler.cxx
21 @author Matthias Richter, Timm Steinbeck
23 @brief Implementation of HLT component handler. */
25 // see header file for class documentation
27 // refer to README to build package
29 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
38 //#include <Riostream.h>
41 //#include "AliHLTStdIncludes.h"
42 #include "AliHLTComponentHandler.h"
43 #include "AliHLTComponent.h"
44 #include "AliHLTDataTypes.h"
45 #include "AliHLTModuleAgent.h"
48 /** ROOT macro for the implementation of ROOT specific class methods */
49 ClassImp(AliHLTComponentHandler)
51 AliHLTComponentHandler::AliHLTComponentHandler()
58 fLibraryMode(kDynamic)
60 // see header file for class documentation
62 // refer to README to build package
64 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
65 memset(&fEnvironment, 0, sizeof(AliHLTComponentEnvironment));
66 AddStandardComponents();
69 AliHLTComponentHandler::AliHLTComponentHandler(AliHLTComponentEnvironment* pEnv)
77 fLibraryMode(kDynamic)
79 // see header file for class documentation
81 memcpy(&fEnvironment, pEnv, sizeof(AliHLTComponentEnvironment));
82 if (pEnv->fLoggingFunc) {
83 // the AliHLTLogging::Init method also sets the stream output
84 // and notification handler to AliLog. This should only be done
85 // if the logging environment contains a logging function
87 AliHLTLogging::Init(pEnv->fLoggingFunc);
90 memset(&fEnvironment, 0, sizeof(AliHLTComponentEnvironment));
93 //SetLocalLoggingLevel(kHLTLogError);
95 //SetLocalLoggingLevel(kHLTLogInfo);
98 AddStandardComponents();
101 AliHLTComponentHandler::~AliHLTComponentHandler()
103 // see header file for class documentation
104 DeleteOwnedComponents();
108 AliHLTComponentHandler* AliHLTComponentHandler::fgpInstance=NULL;
109 int AliHLTComponentHandler::fgNofInstances=0;
111 AliHLTComponentHandler* AliHLTComponentHandler::CreateHandler()
113 // see header file for class documentation
114 if (!fgpInstance) fgpInstance=new AliHLTComponentHandler;
119 int AliHLTComponentHandler::Destroy()
121 // see header file for class documentation
123 if (fgpInstance==this) {
124 nofInstances=fgNofInstances--;
126 if (nofInstances==0) delete this;
130 int AliHLTComponentHandler::AnnounceVersion()
132 // see header file for class documentation
134 #ifdef PACKAGE_STRING
135 void HLTbaseCompileInfo( char*& date, char*& time);
138 HLTbaseCompileInfo(date, time);
139 if (!date) date="unknown";
140 if (!time) time="unknown";
141 HLTImportant("%s build on %s (%s)", PACKAGE_STRING, date, time);
143 HLTImportant("ALICE High Level Trigger build on %s (%s) (embedded AliRoot build)", __DATE__, __TIME__);
148 Int_t AliHLTComponentHandler::AddComponent(AliHLTComponent* pSample)
150 // see header file for class documentation
152 if (pSample==NULL) return -EINVAL;
153 if ((iResult=RegisterComponent(pSample))>=0) {
154 //HLTDebug("sample %s (%p) managed by handler", pSample->GetComponentID(), pSample);
155 fOwnedComponents.push_back(pSample);
160 Int_t AliHLTComponentHandler::RegisterComponent(AliHLTComponent* pSample)
162 // see header file for class documentation
165 if (FindComponent(pSample->GetComponentID())==NULL) {
166 iResult=InsertComponent(pSample);
168 HLTInfo("component %s registered", pSample->GetComponentID());
171 // component already registered
172 HLTDebug("component %s already registered, skipped", pSample->GetComponentID());
181 int AliHLTComponentHandler::DeregisterComponent( const char* componentID )
183 // see header file for class documentation
187 HLTWarning("not yet implemented, please notify the developers if you need this function");
194 Int_t AliHLTComponentHandler::ScheduleRegister(AliHLTComponent* pSample)
196 // see header file for class documentation
199 fScheduleList.push_back(pSample);
206 int AliHLTComponentHandler::CreateComponent(const char* componentID, void* pEnvParam, int argc, const char** argv, AliHLTComponent*& component, const char* cdbPath )
208 // see header file for class documentation
211 AliHLTComponent* pSample=FindComponent(componentID);
213 component=pSample->Spawn();
215 HLTDebug("component \"%s\" created (%p)", componentID, component);
216 component->InitCDB(cdbPath, this);
217 if ((iResult=component->Init(&fEnvironment, pEnvParam, argc, argv))!=0) {
218 HLTError("Initialization of component \"%s\" failed with error %d", componentID, iResult);
223 HLTError("can not spawn component \"%s\"", componentID);
227 HLTWarning("can not find component \"%s\"", componentID);
236 Int_t AliHLTComponentHandler::FindComponentIndex(const char* componentID)
238 // see header file for class documentation
241 AliHLTComponentPList::iterator element=fComponentList.begin();
242 while (element!=fComponentList.end() && iResult>=0) {
243 if (strcmp(componentID, (*element)->GetComponentID())==0) {
249 if (element==fComponentList.end()) iResult=-ENOENT;
256 AliHLTComponent* AliHLTComponentHandler::FindComponent(const char* componentID)
258 // see header file for class documentation
259 AliHLTComponent* pSample=NULL;
260 Int_t index=FindComponentIndex(componentID);
262 pSample=(AliHLTComponent*)fComponentList.at(index);
267 Int_t AliHLTComponentHandler::InsertComponent(AliHLTComponent* pSample)
269 // see header file for class documentation
272 fComponentList.push_back(pSample);
279 void AliHLTComponentHandler::List()
281 // see header file for class documentation
282 AliHLTComponentPList::iterator element=fComponentList.begin();
284 while (element!=fComponentList.end()) {
285 HLTInfo("%d. %s", index++, (*element++)->GetComponentID());
289 int AliHLTComponentHandler::HasOutputData( const char* componentID)
291 // see header file for class documentation
293 AliHLTComponent* pSample=FindComponent(componentID);
295 AliHLTComponent::TComponentType ct=AliHLTComponent::kUnknown;
296 ct=pSample->GetComponentType();
297 iResult=(ct==AliHLTComponent::kSource || ct==AliHLTComponent::kProcessor);
304 void AliHLTComponentHandler::SetEnvironment(AliHLTComponentEnvironment* pEnv)
306 // see header file for class documentation
308 memcpy(&fEnvironment, pEnv, sizeof(AliHLTComponentEnvironment));
309 if (fEnvironment.fLoggingFunc) {
310 // the AliHLTLogging::Init method also sets the stream output
311 // and notification handler to AliLog. This should only be done
312 // if the logging environment contains a logging function
314 AliHLTLogging::Init(fEnvironment.fLoggingFunc);
319 AliHLTComponentHandler::TLibraryMode AliHLTComponentHandler::SetLibraryMode(TLibraryMode mode)
321 // see header file for class documentation
322 TLibraryMode old=fLibraryMode;
327 int AliHLTComponentHandler::LoadLibrary( const char* libraryPath, int bActivateAgents)
329 // see header file for class documentation
332 // first activate all agents which are already loaded
333 if (bActivateAgents) ActivateAgents();
335 // set the global component handler for static component registration
336 AliHLTComponent::SetGlobalComponentHandler(this);
338 AliHLTLibHandle hLib;
339 AliHLTLibHandle* phSearch=FindLibrary(libraryPath);
340 const char* loadtype="";
342 // use interface to the dynamic linking loader
344 // exeption does not help in Root context, the Root exeption
345 // handler always catches the exeption before. Have to find out
346 // how exeptions can be used in Root
348 hLib.fHandle=dlopen(libraryPath, RTLD_NOW);
353 // error message printed further down
354 loadtype="dlopen exeption";
358 // use ROOT dynamic loader
359 // check if the library was already loaded, as Load returns
360 // 'failure' if the library was already loaded
363 int* pRootHandle=reinterpret_cast<int*>(phSearch->fHandle);
365 HLTDebug("instance %d of library %s loaded", (*pRootHandle), libraryPath);
366 hLib.fHandle=pRootHandle;
369 if (hLib.fHandle==NULL && gSystem->Load(libraryPath)>=0) {
370 int* pRootHandle=new int;
371 if (pRootHandle) *pRootHandle=1;
372 hLib.fHandle=pRootHandle;
373 //HLTDebug("library %s loaded via gSystem", libraryPath);
379 // error message printed further down
380 loadtype="gSystem exeption";
383 #endif //HAVE_DLFCN_H
384 if (hLib.fHandle!=NULL) {
385 // create TString object to store library path and use pointer as handle
386 hLib.fName=new TString(libraryPath);
387 hLib.fMode=fLibraryMode;
388 fLibraryList.insert(fLibraryList.begin(), hLib);
390 HLTImportant("library %s loaded (%s%s)", libraryPath, hLib.fMode==kStatic?"persistent, ":"", loadtype);
391 typedef void (*CompileInfo)( char*& date, char*& time);
392 CompileInfo fctInfo=(CompileInfo)FindSymbol(libraryPath, "CompileInfo");
396 (*fctInfo)(date, time);
397 if (!date) date="unknown";
398 if (!time) time="unknown";
399 HLTImportant("build on %s (%s)", date, time);
401 HLTImportant("no build info available (possible AliRoot embedded build)");
405 // static registration of components when library is loaded
406 iResult=RegisterScheduledComponents();
409 HLTError("can not load library %s (%s)", libraryPath, loadtype);
411 HLTError("dlopen error: %s", dlerror());
412 #endif //HAVE_DLFCN_H
419 AliHLTComponent::UnsetGlobalComponentHandler();
422 // alternative dynamic registration by library agents
423 // !!! has to be done after UnsetGlobalComponentHandler
424 if (bActivateAgents) ActivateAgents();
433 int AliHLTComponentHandler::UnloadLibrary( const char* libraryPath )
435 // see header file for class documentation
438 vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
439 while (element!=fLibraryList.end()) {
440 TString* pName=reinterpret_cast<TString*>((*element).fName);
441 if (pName->CompareTo(libraryPath)==0) {
442 UnloadLibrary(*element);
443 fLibraryList.erase(element);
454 int AliHLTComponentHandler::UnloadLibrary(AliHLTComponentHandler::AliHLTLibHandle &handle)
456 // see header file for class documentation
458 fgAliLoggingFunc=NULL;
459 TString* pName=reinterpret_cast<TString*>(handle.fName);
460 if (handle.fMode!=kStatic) {
462 // exeption does not help in Root context, the Root exeption
463 // handler always catches the exeption before. Have to find out
464 // how exeptions can be used in Root
467 dlclose(handle.fHandle);
471 HLTError("exeption caught during dlclose of library %s", pName!=NULL?pName->Data():"");
475 int* pCount=reinterpret_cast<int*>(handle.fHandle);
476 if (--(*pCount)==0) {
478 /** Matthias 26.04.2007
479 * I spent about a week to investigate a bug which seems to be in ROOT.
480 * Under certain circumstances, TSystem::Unload crashes. The crash occured
481 * for the first time, when libAliHLTUtil was loaded from AliHLTSystem right
482 * after the ComponentHandler was created. It does not occur when dlopen is
484 * It has most likely to do with the garbage collection and automatic
485 * cleanup in ROOT. The crash occurs when ROOT is terminated and before
486 * an instance of AliHLTSystem was created.
487 * root [0] AliHLTSystem gHLT
488 * It does not occur when the instance was created dynamically (but not even
490 * root [0] AliHLTSystem* gHLT=new AliHLTSystem
492 * For that reason, the libraries are not unloaded here, even though there
493 * will be memory leaks.
494 gSystem->Unload(pName->Data());
498 HLTError("missing library name, can not unload");
502 #endif //HAVE_DLFCN_H
504 HLTDebug("unload library %s", pName->Data());
506 HLTWarning("missing name for unloaded library");
518 int AliHLTComponentHandler::UnloadLibraries()
520 // see header file for class documentation
522 vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
523 while (element!=fLibraryList.end()) {
524 UnloadLibrary(*element);
525 fLibraryList.erase(element);
526 element=fLibraryList.begin();
531 void* AliHLTComponentHandler::FindSymbol(const char* library, const char* symbol)
533 // see header file for class documentation
534 AliHLTLibHandle* hLib=FindLibrary(library);
535 if (hLib==NULL) return NULL;
538 pFunc=dlsym(hLib->fHandle, symbol);
540 TString* name=reinterpret_cast<TString*>(hLib->fName);
541 pFunc=gSystem->DynFindSymbol(name->Data(), symbol);
546 AliHLTComponentHandler::AliHLTLibHandle* AliHLTComponentHandler::FindLibrary(const char* library)
548 // see header file for class documentation
549 AliHLTLibHandle* hLib=NULL;
550 vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
551 while (element!=fLibraryList.end()) {
552 TString* name=reinterpret_cast<TString*>((*element).fName);
553 if (name->CompareTo(library)==0) {
562 int AliHLTComponentHandler::AddStandardComponents()
564 // see header file for class documentation
566 AliHLTComponent::SetGlobalComponentHandler(this);
567 AliHLTComponent::UnsetGlobalComponentHandler();
568 iResult=RegisterScheduledComponents();
572 int AliHLTComponentHandler::RegisterScheduledComponents()
574 // see header file for class documentation
576 AliHLTComponentPList::iterator element=fScheduleList.begin();
578 while (element!=fScheduleList.end()) {
579 iLocalResult=RegisterComponent(*element);
580 if (iResult==0) iResult=iLocalResult;
581 fScheduleList.erase(element);
582 element=fScheduleList.begin();
587 int AliHLTComponentHandler::ActivateAgents(const AliHLTModuleAgent** blackList, int size)
589 // see header file for class documentation
591 AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
592 while (pAgent && iResult>=0) {
595 for (; i<size; i++) {
596 if (blackList[i]==pAgent) break;
599 // this agent was in the list
600 pAgent=AliHLTModuleAgent::GetNextAgent();
605 pAgent->ActivateComponentHandler(this);
606 pAgent=AliHLTModuleAgent::GetNextAgent();
611 int AliHLTComponentHandler::DeleteOwnedComponents()
613 // see header file for class documentation
615 AliHLTComponentPList::iterator element=fOwnedComponents.begin();
616 while (element!=fOwnedComponents.end()) {
617 //DeregisterComponent((*element)->GetComponentID());
618 // exeption does not help in Root context, the Root exeption
619 // handler always catches the exeption before. Have to find out
620 // how exeptions can be used in Root
626 HLTError("delete managed sample %p", *element);
629 fOwnedComponents.erase(element);
630 element=fOwnedComponents.begin();