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()
59 // see header file for class documentation
61 // refer to README to build package
63 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
64 memset(&fEnvironment, 0, sizeof(AliHLTComponentEnvironment));
65 AddStandardComponents();
68 AliHLTComponentHandler::AliHLTComponentHandler(AliHLTComponentEnvironment* pEnv)
77 // see header file for class documentation
79 memcpy(&fEnvironment, pEnv, sizeof(AliHLTComponentEnvironment));
80 if (pEnv->fLoggingFunc) {
81 // the AliHLTLogging::Init method also sets the stream output
82 // and notification handler to AliLog. This should only be done
83 // if the logging environment contains a logging function
85 AliHLTLogging::Init(pEnv->fLoggingFunc);
88 memset(&fEnvironment, 0, sizeof(AliHLTComponentEnvironment));
91 //SetLocalLoggingLevel(kHLTLogError);
93 //SetLocalLoggingLevel(kHLTLogInfo);
96 AddStandardComponents();
99 AliHLTComponentHandler::~AliHLTComponentHandler()
101 // see header file for class documentation
102 DeleteOwnedComponents();
106 int AliHLTComponentHandler::AnnounceVersion()
108 // see header file for class documentation
110 #ifdef PACKAGE_STRING
111 void HLTbaseCompileInfo( char*& date, char*& time);
114 HLTbaseCompileInfo(date, time);
115 if (!date) date="unknown";
116 if (!time) time="unknown";
117 HLTInfo("%s build on %s (%s)", PACKAGE_STRING, date, time);
119 HLTInfo("ALICE High Level Trigger build on %s (%s) (embedded AliRoot build)", __DATE__, __TIME__);
124 Int_t AliHLTComponentHandler::AddComponent(AliHLTComponent* pSample)
126 // see header file for class documentation
128 if (pSample==NULL) return -EINVAL;
129 if ((iResult=RegisterComponent(pSample))>=0) {
130 //HLTDebug("sample %s (%p) managed by handler", pSample->GetComponentID(), pSample);
131 fOwnedComponents.push_back(pSample);
136 Int_t AliHLTComponentHandler::RegisterComponent(AliHLTComponent* pSample)
138 // see header file for class documentation
141 if (FindComponent(pSample->GetComponentID())==NULL) {
142 iResult=InsertComponent(pSample);
144 HLTInfo("component %s registered", pSample->GetComponentID());
147 // component already registered
148 HLTDebug("component %s already registered, skipped", pSample->GetComponentID());
157 int AliHLTComponentHandler::DeregisterComponent( const char* componentID )
159 // see header file for class documentation
163 HLTWarning("not yet implemented, please notify the developers if you need this function");
170 Int_t AliHLTComponentHandler::ScheduleRegister(AliHLTComponent* pSample)
172 // see header file for class documentation
175 fScheduleList.push_back(pSample);
182 int AliHLTComponentHandler::CreateComponent(const char* componentID, void* pEnvParam, int argc, const char** argv, AliHLTComponent*& component )
184 // see header file for class documentation
187 AliHLTComponent* pSample=FindComponent(componentID);
189 component=pSample->Spawn();
191 HLTDebug("component \"%s\" created (%p)", componentID, component);
192 if ((iResult=component->Init(&fEnvironment, pEnvParam, argc, argv))!=0) {
193 HLTError("Initialization of component \"%s\" failed with error %d", componentID, iResult);
198 HLTError("can not spawn component \"%s\"", componentID);
202 HLTWarning("can not find component \"%s\"", componentID);
211 Int_t AliHLTComponentHandler::FindComponentIndex(const char* componentID)
213 // see header file for class documentation
216 AliHLTComponentPList::iterator element=fComponentList.begin();
217 while (element!=fComponentList.end() && iResult>=0) {
218 if (strcmp(componentID, (*element)->GetComponentID())==0) {
224 if (element==fComponentList.end()) iResult=-ENOENT;
231 AliHLTComponent* AliHLTComponentHandler::FindComponent(const char* componentID)
233 // see header file for class documentation
234 AliHLTComponent* pSample=NULL;
235 Int_t index=FindComponentIndex(componentID);
237 pSample=(AliHLTComponent*)fComponentList.at(index);
242 Int_t AliHLTComponentHandler::InsertComponent(AliHLTComponent* pSample)
244 // see header file for class documentation
247 fComponentList.push_back(pSample);
254 void AliHLTComponentHandler::List()
256 // see header file for class documentation
257 AliHLTComponentPList::iterator element=fComponentList.begin();
259 while (element!=fComponentList.end()) {
260 HLTInfo("%d. %s", index++, (*element++)->GetComponentID());
264 int AliHLTComponentHandler::HasOutputData( const char* componentID)
266 // see header file for class documentation
268 AliHLTComponent* pSample=FindComponent(componentID);
270 AliHLTComponent::TComponentType ct=AliHLTComponent::kUnknown;
271 ct=pSample->GetComponentType();
272 iResult=(ct==AliHLTComponent::kSource || ct==AliHLTComponent::kProcessor);
279 void AliHLTComponentHandler::SetEnvironment(AliHLTComponentEnvironment* pEnv)
281 // see header file for class documentation
283 memcpy(&fEnvironment, pEnv, sizeof(AliHLTComponentEnvironment));
284 if (fEnvironment.fLoggingFunc) {
285 // the AliHLTLogging::Init method also sets the stream output
286 // and notification handler to AliLog. This should only be done
287 // if the logging environment contains a logging function
289 AliHLTLogging::Init(fEnvironment.fLoggingFunc);
294 AliHLTComponentHandler::TLibraryMode AliHLTComponentHandler::SetLibraryMode(TLibraryMode mode)
296 // see header file for class documentation
297 TLibraryMode old=fLibraryMode;
302 int AliHLTComponentHandler::LoadLibrary( const char* libraryPath, int bActivateAgents)
304 // see header file for class documentation
307 // first activate all agents which are already loaded
308 if (bActivateAgents) ActivateAgents();
310 // set the global component handler for static component registration
311 AliHLTComponent::SetGlobalComponentHandler(this);
313 AliHLTLibHandle hLib;
314 const char* loadtype="";
316 // use interface to the dynamic linking loader
318 hLib.fHandle=dlopen(libraryPath, RTLD_NOW);
322 // error message printed further down
323 loadtype="dlopen exeption";
326 // use ROOT dynamic loader
327 // check if the library was already loaded, as Load returns
328 // 'failure' if the library was already loaded
330 AliHLTLibHandle* pLib=FindLibrary(libraryPath);
332 int* pRootHandle=reinterpret_cast<int*>(pLib->fHandle);
334 HLTDebug("instance %d of library %s loaded", (*pRootHandle), libraryPath);
335 hLib.fHandle=pRootHandle;
338 if (hLib.fHandle==NULL && gSystem->Load(libraryPath)==0) {
339 int* pRootHandle=new int;
340 if (pRootHandle) *pRootHandle=1;
341 hLib.fHandle=pRootHandle;
342 //HLTDebug("library %s loaded via gSystem", libraryPath);
347 // error message printed further down
348 loadtype="gSystem exeption";
350 #endif //HAVE_DLFCN_H
351 if (hLib.fHandle!=NULL) {
352 // create TString object to store library path and use pointer as handle
353 hLib.fName=new TString(libraryPath);
354 hLib.fMode=fLibraryMode;
355 HLTInfo("library %s loaded (%s%s)", libraryPath, hLib.fMode==kStatic?"persistent, ":"", loadtype);
356 fLibraryList.insert(fLibraryList.begin(), hLib);
357 typedef void (*CompileInfo)( char*& date, char*& time);
358 CompileInfo fctInfo=(CompileInfo)FindSymbol(libraryPath, "CompileInfo");
362 (*fctInfo)(date, time);
363 if (!date) date="unknown";
364 if (!time) time="unknown";
365 HLTInfo("build on %s (%s)", date, time);
367 HLTInfo("no build info available (possible AliRoot embedded build)");
370 // static registration of components when library is loaded
371 iResult=RegisterScheduledComponents();
374 HLTError("can not load library %s (%s)", libraryPath, loadtype);
376 HLTError("dlopen error: %s", dlerror());
377 #endif //HAVE_DLFCN_H
384 AliHLTComponent::UnsetGlobalComponentHandler();
387 // alternative dynamic registration by library agents
388 // !!! has to be done after UnsetGlobalComponentHandler
389 if (bActivateAgents) ActivateAgents();
398 int AliHLTComponentHandler::UnloadLibrary( const char* libraryPath )
400 // see header file for class documentation
403 vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
404 while (element!=fLibraryList.end()) {
405 TString* pName=reinterpret_cast<TString*>((*element).fName);
406 if (pName->CompareTo(libraryPath)==0) {
407 UnloadLibrary(*element);
408 fLibraryList.erase(element);
419 int AliHLTComponentHandler::UnloadLibrary(AliHLTComponentHandler::AliHLTLibHandle &handle)
421 // see header file for class documentation
423 fgAliLoggingFunc=NULL;
424 TString* pName=reinterpret_cast<TString*>(handle.fName);
425 if (handle.fMode!=kStatic) {
428 dlclose(handle.fHandle);
431 HLTError("exeption caught during dlclose of library %s", pName!=NULL?pName->Data():"");
434 int* pCount=reinterpret_cast<int*>(handle.fHandle);
435 if (--(*pCount)==0) {
437 /** Matthias 26.04.2007
438 * I spent about a week to investigate a bug which seems to be in ROOT.
439 * Under certain circumstances, TSystem::Unload crashes. The crash occured
440 * for the first time, when libAliHLTUtil was loaded from AliHLTSystem right
441 * after the ComponentHandler was created. It does not occur when dlopen is
443 * It has most likely to do with the garbage collection and automatic
444 * cleanup in ROOT. The crash occurs when ROOT is terminated and before
445 * an instance of AliHLTSystem was created.
446 * root [0] AliHLTSystem gHLT
447 * It does not occur when the instance was created dynamically (but not even
449 * root [0] AliHLTSystem* gHLT=new AliHLTSystem
451 * For that reason, the libraries are not unloaded here, even though there
452 * will be memory leaks.
453 gSystem->Unload(pName->Data());
457 HLTError("missing library name, can not unload");
461 #endif //HAVE_DLFCN_H
463 HLTDebug("unload library %s", pName->Data());
465 HLTWarning("missing name for unloaded library");
477 int AliHLTComponentHandler::UnloadLibraries()
479 // see header file for class documentation
481 vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
482 while (element!=fLibraryList.end()) {
483 UnloadLibrary(*element);
484 fLibraryList.erase(element);
485 element=fLibraryList.begin();
490 void* AliHLTComponentHandler::FindSymbol(const char* library, const char* symbol)
492 // see header file for class documentation
493 AliHLTLibHandle* hLib=FindLibrary(library);
494 if (hLib==NULL) return NULL;
497 pFunc=dlsym(hLib->fHandle, symbol);
499 TString* name=reinterpret_cast<TString*>(hLib->fName);
500 pFunc=gSystem->DynFindSymbol(name->Data(), symbol);
505 AliHLTComponentHandler::AliHLTLibHandle* AliHLTComponentHandler::FindLibrary(const char* library)
507 // see header file for class documentation
508 AliHLTLibHandle* hLib=NULL;
509 vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
510 while (element!=fLibraryList.end()) {
511 TString* name=reinterpret_cast<TString*>((*element).fName);
512 if (name->CompareTo(library)==0) {
521 int AliHLTComponentHandler::AddStandardComponents()
523 // see header file for class documentation
525 AliHLTComponent::SetGlobalComponentHandler(this);
526 AliHLTComponent::UnsetGlobalComponentHandler();
527 iResult=RegisterScheduledComponents();
531 int AliHLTComponentHandler::RegisterScheduledComponents()
533 // see header file for class documentation
535 AliHLTComponentPList::iterator element=fScheduleList.begin();
537 while (element!=fScheduleList.end()) {
538 iLocalResult=RegisterComponent(*element);
539 if (iResult==0) iResult=iLocalResult;
540 fScheduleList.erase(element);
541 element=fScheduleList.begin();
546 int AliHLTComponentHandler::ActivateAgents(const AliHLTModuleAgent** blackList, int size)
548 // see header file for class documentation
550 AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
551 while (pAgent && iResult>=0) {
554 for (; i<size; i++) {
555 if (blackList[i]==pAgent) break;
558 // this agent was in the list
559 pAgent=AliHLTModuleAgent::GetNextAgent();
564 pAgent->ActivateComponentHandler(this);
565 pAgent=AliHLTModuleAgent::GetNextAgent();
570 int AliHLTComponentHandler::DeleteOwnedComponents()
572 // see header file for class documentation
574 AliHLTComponentPList::iterator element=fOwnedComponents.begin();
575 while (element!=fOwnedComponents.end()) {
576 //DeregisterComponent((*element)->GetComponentID());
581 HLTError("delete managed sample %p", *element);
583 fOwnedComponents.erase(element);
584 element=fOwnedComponents.begin();