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. */
32 //#include <Riostream.h>
35 //#include "AliHLTStdIncludes.h"
36 #include "AliHLTComponentHandler.h"
37 #include "AliHLTComponent.h"
38 #include "AliHLTDataTypes.h"
39 #include "AliHLTModuleAgent.h"
42 /** ROOT macro for the implementation of ROOT specific class methods */
43 ClassImp(AliHLTComponentHandler)
45 AliHLTComponentHandler::AliHLTComponentHandler()
53 // see header file for class documentation
55 // refer to README to build package
57 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
58 memset(&fEnvironment, 0, sizeof(AliHLTComponentEnvironment));
59 AddStandardComponents();
62 AliHLTComponentHandler::AliHLTComponentHandler(AliHLTComponentEnvironment* pEnv)
71 // see header file for class documentation
73 memcpy(&fEnvironment, pEnv, sizeof(AliHLTComponentEnvironment));
74 if (pEnv->fLoggingFunc) {
75 // the AliHLTLogging::Init method also sets the stream output
76 // and notification handler to AliLog. This should only be done
77 // if the logging environment contains a logging function
79 AliHLTLogging::Init(pEnv->fLoggingFunc);
82 memset(&fEnvironment, 0, sizeof(AliHLTComponentEnvironment));
85 //SetLocalLoggingLevel(kHLTLogError);
87 //SetLocalLoggingLevel(kHLTLogInfo);
90 AddStandardComponents();
93 AliHLTComponentHandler::~AliHLTComponentHandler()
95 // see header file for class documentation
96 DeleteOwnedComponents();
100 int AliHLTComponentHandler::AnnounceVersion()
102 // see header file for class documentation
104 #ifdef PACKAGE_STRING
105 void HLTbaseCompileInfo( char*& date, char*& time);
108 HLTbaseCompileInfo(date, time);
109 if (!date) date="unknown";
110 if (!time) time="unknown";
111 HLTInfo("%s build on %s (%s)", PACKAGE_STRING, date, time);
113 HLTInfo("ALICE High Level Trigger build on %s (%s) (embedded AliRoot build)", __DATE__, __TIME__);
118 Int_t AliHLTComponentHandler::AddComponent(AliHLTComponent* pSample)
120 // see header file for class documentation
122 if (pSample==NULL) return -EINVAL;
123 if ((iResult=RegisterComponent(pSample))>=0) {
124 //HLTDebug("sample %s (%p) managed by handler", pSample->GetComponentID(), pSample);
125 fOwnedComponents.push_back(pSample);
130 Int_t AliHLTComponentHandler::RegisterComponent(AliHLTComponent* pSample)
132 // see header file for class documentation
135 if (FindComponent(pSample->GetComponentID())==NULL) {
136 iResult=InsertComponent(pSample);
138 HLTInfo("component %s registered", pSample->GetComponentID());
141 // component already registered
142 HLTDebug("component %s already registered, skipped", pSample->GetComponentID());
151 int AliHLTComponentHandler::DeregisterComponent( const char* componentID )
153 // see header file for class documentation
157 HLTWarning("not yet implemented, please notify the developers if you need this function");
164 Int_t AliHLTComponentHandler::ScheduleRegister(AliHLTComponent* pSample)
166 // see header file for class documentation
169 fScheduleList.push_back(pSample);
176 int AliHLTComponentHandler::CreateComponent(const char* componentID, void* pEnvParam, int argc, const char** argv, AliHLTComponent*& component )
178 // see header file for class documentation
181 AliHLTComponent* pSample=FindComponent(componentID);
183 component=pSample->Spawn();
185 HLTDebug("component \"%s\" created (%p)", componentID, component);
186 if ((iResult=component->Init(&fEnvironment, pEnvParam, argc, argv))!=0) {
187 HLTError("Initialization of component \"%s\" failed with error %d", componentID, iResult);
192 HLTError("can not spawn component \"%s\"", componentID);
196 HLTWarning("can not find component \"%s\"", componentID);
205 Int_t AliHLTComponentHandler::FindComponentIndex(const char* componentID)
207 // see header file for class documentation
210 vector<AliHLTComponent*>::iterator element=fComponentList.begin();
211 while (element!=fComponentList.end() && iResult>=0) {
212 if (strcmp(componentID, (*element)->GetComponentID())==0) {
218 if (element==fComponentList.end()) iResult=-ENOENT;
225 AliHLTComponent* AliHLTComponentHandler::FindComponent(const char* componentID)
227 // see header file for class documentation
228 AliHLTComponent* pSample=NULL;
229 Int_t index=FindComponentIndex(componentID);
231 pSample=(AliHLTComponent*)fComponentList.at(index);
236 Int_t AliHLTComponentHandler::InsertComponent(AliHLTComponent* pSample)
238 // see header file for class documentation
241 fComponentList.push_back(pSample);
248 void AliHLTComponentHandler::List()
250 // see header file for class documentation
251 vector<AliHLTComponent*>::iterator element=fComponentList.begin();
253 while (element!=fComponentList.end()) {
254 HLTInfo("%d. %s", index++, (*element++)->GetComponentID());
258 int AliHLTComponentHandler::HasOutputData( const char* componentID)
260 // see header file for class documentation
262 AliHLTComponent* pSample=FindComponent(componentID);
264 AliHLTComponent::TComponentType ct=AliHLTComponent::kUnknown;
265 ct=pSample->GetComponentType();
266 iResult=(ct==AliHLTComponent::kSource || ct==AliHLTComponent::kProcessor);
273 void AliHLTComponentHandler::SetEnvironment(AliHLTComponentEnvironment* pEnv)
275 // see header file for class documentation
277 memcpy(&fEnvironment, pEnv, sizeof(AliHLTComponentEnvironment));
278 if (fEnvironment.fLoggingFunc) {
279 // the AliHLTLogging::Init method also sets the stream output
280 // and notification handler to AliLog. This should only be done
281 // if the logging environment contains a logging function
283 AliHLTLogging::Init(fEnvironment.fLoggingFunc);
288 AliHLTComponentHandler::TLibraryMode AliHLTComponentHandler::SetLibraryMode(TLibraryMode mode)
290 // see header file for class documentation
291 TLibraryMode old=fLibraryMode;
296 int AliHLTComponentHandler::LoadLibrary( const char* libraryPath, int bActivateAgents)
298 // see header file for class documentation
301 // first activate all agents which are already loaded
302 if (bActivateAgents) ActivateAgents();
304 // set the global component handler for static component registration
305 AliHLTComponent::SetGlobalComponentHandler(this);
307 AliHLTLibHandle hLib;
308 const char* loadtype="";
310 // use interface to the dynamic linking loader
312 hLib.fHandle=dlopen(libraryPath, RTLD_NOW);
316 // error message printed further down
317 loadtype="dlopen exeption";
320 // use ROOT dynamic loader
321 // check if the library was already loaded, as Load returns
322 // 'failure' if the library was already loaded
324 AliHLTLibHandle* pLib=FindLibrary(libraryPath);
326 int* pRootHandle=reinterpret_cast<int*>(pLib->fHandle);
328 HLTDebug("instance %d of library %s loaded", (*pRootHandle), libraryPath);
329 hLib.fHandle=pRootHandle;
332 if (hLib.fHandle==NULL && gSystem->Load(libraryPath)==0) {
333 int* pRootHandle=new int;
334 if (pRootHandle) *pRootHandle=1;
335 hLib.fHandle=pRootHandle;
336 //HLTDebug("library %s loaded via gSystem", libraryPath);
341 // error message printed further down
342 loadtype="gSystem exeption";
344 #endif //HAVE_DLFCN_H
345 if (hLib.fHandle!=NULL) {
346 // create TString object to store library path and use pointer as handle
347 hLib.fName=new TString(libraryPath);
348 hLib.fMode=fLibraryMode;
349 HLTInfo("library %s loaded (%s%s)", libraryPath, hLib.fMode==kStatic?"persistent, ":"", loadtype);
350 fLibraryList.insert(fLibraryList.begin(), hLib);
351 typedef void (*CompileInfo)( char*& date, char*& time);
352 CompileInfo fctInfo=(CompileInfo)FindSymbol(libraryPath, "CompileInfo");
356 (*fctInfo)(date, time);
357 if (!date) date="unknown";
358 if (!time) time="unknown";
359 HLTInfo("build on %s (%s)", date, time);
361 HLTInfo("no build info available (possible AliRoot embedded build)");
364 // static registration of components when library is loaded
365 iResult=RegisterScheduledComponents();
368 HLTError("can not load library %s (%s)", libraryPath, loadtype);
370 HLTError("dlopen error: %s", dlerror());
371 #endif //HAVE_DLFCN_H
378 AliHLTComponent::UnsetGlobalComponentHandler();
381 // alternative dynamic registration by library agents
382 // !!! has to be done after UnsetGlobalComponentHandler
383 if (bActivateAgents) ActivateAgents();
392 int AliHLTComponentHandler::UnloadLibrary( const char* libraryPath )
394 // see header file for class documentation
397 vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
398 while (element!=fLibraryList.end()) {
399 TString* pName=reinterpret_cast<TString*>((*element).fName);
400 if (pName->CompareTo(libraryPath)==0) {
401 UnloadLibrary(*element);
402 fLibraryList.erase(element);
413 int AliHLTComponentHandler::UnloadLibrary(AliHLTComponentHandler::AliHLTLibHandle &handle)
415 // see header file for class documentation
417 fgAliLoggingFunc=NULL;
418 TString* pName=reinterpret_cast<TString*>(handle.fName);
419 if (handle.fMode!=kStatic) {
422 dlclose(handle.fHandle);
425 HLTError("exeption caught during dlclose of library %s", pName!=NULL?pName->Data():"");
428 int* pCount=reinterpret_cast<int*>(handle.fHandle);
429 if (--(*pCount)==0) {
431 /** Matthias 26.04.2007
432 * I spent about a week to investigate a bug which seems to be in ROOT.
433 * Under certain circumstances, TSystem::Unload crashes. The crash occured
434 * for the first time, when libAliHLTUtil was loaded from AliHLTSystem right
435 * after the ComponentHandler was created. It does not occur when dlopen is
437 * It has most likely to do with the garbage collection and automatic
438 * cleanup in ROOT. The crash occurs when ROOT is terminated and before
439 * an instance of AliHLTSystem was created.
440 * root [0] AliHLTSystem gHLT
441 * It does not occur when the instance was created dynamically (but not even
443 * root [0] AliHLTSystem* gHLT=new AliHLTSystem
445 * For that reason, the libraries are not unloaded here, even though there
446 * will be memory leaks.
447 gSystem->Unload(pName->Data());
451 HLTError("missing library name, can not unload");
455 #endif //HAVE_DLFCN_H
457 HLTDebug("unload library %s", pName->Data());
459 HLTWarning("missing name for unloaded library");
471 int AliHLTComponentHandler::UnloadLibraries()
473 // see header file for class documentation
475 vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
476 while (element!=fLibraryList.end()) {
477 UnloadLibrary(*element);
478 fLibraryList.erase(element);
479 element=fLibraryList.begin();
484 void* AliHLTComponentHandler::FindSymbol(const char* library, const char* symbol)
486 // see header file for class documentation
487 AliHLTLibHandle* hLib=FindLibrary(library);
488 if (hLib==NULL) return NULL;
491 pFunc=dlsym(hLib->fHandle, symbol);
493 TString* name=reinterpret_cast<TString*>(hLib->fName);
494 pFunc=gSystem->DynFindSymbol(name->Data(), symbol);
499 AliHLTComponentHandler::AliHLTLibHandle* AliHLTComponentHandler::FindLibrary(const char* library)
501 // see header file for class documentation
502 AliHLTLibHandle* hLib=NULL;
503 vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
504 while (element!=fLibraryList.end()) {
505 TString* name=reinterpret_cast<TString*>((*element).fName);
506 if (name->CompareTo(library)==0) {
515 int AliHLTComponentHandler::AddStandardComponents()
517 // see header file for class documentation
519 AliHLTComponent::SetGlobalComponentHandler(this);
520 AliHLTComponent::UnsetGlobalComponentHandler();
521 iResult=RegisterScheduledComponents();
525 int AliHLTComponentHandler::RegisterScheduledComponents()
527 // see header file for class documentation
529 vector<AliHLTComponent*>::iterator element=fScheduleList.begin();
531 while (element!=fScheduleList.end()) {
532 iLocalResult=RegisterComponent(*element);
533 if (iResult==0) iResult=iLocalResult;
534 fScheduleList.erase(element);
535 element=fScheduleList.begin();
540 int AliHLTComponentHandler::ActivateAgents(const AliHLTModuleAgent** blackList, int size)
542 // see header file for class documentation
544 AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
545 while (pAgent && iResult>=0) {
548 for (; i<size; i++) {
549 if (blackList[i]==pAgent) break;
552 // this agent was in the list
553 pAgent=AliHLTModuleAgent::GetNextAgent();
558 pAgent->ActivateComponentHandler(this);
559 pAgent=AliHLTModuleAgent::GetNextAgent();
564 int AliHLTComponentHandler::DeleteOwnedComponents()
566 // see header file for class documentation
568 vector<AliHLTComponent*>::iterator element=fOwnedComponents.begin();
569 while (element!=fOwnedComponents.end()) {
570 //DeregisterComponent((*element)->GetComponentID());
575 HLTError("delete managed sample %p", *element);
577 fOwnedComponents.erase(element);
578 element=fOwnedComponents.begin();