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 "AliHLTSystem.h"
42 // the standard components
43 // #include "AliHLTFilePublisher.h"
44 // #include "AliHLTFileWriter.h"
45 // #include "AliHLTRootFilePublisherComponent.h"
46 // #include "AliHLTRootFileWriterComponent.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));
89 AddStandardComponents();
92 AliHLTComponentHandler::~AliHLTComponentHandler()
94 // see header file for class documentation
95 DeleteStandardComponents();
99 int AliHLTComponentHandler::AnnounceVersion()
101 // see header file for class documentation
103 #ifdef PACKAGE_STRING
104 void HLTbaseCompileInfo( char*& date, char*& time);
107 HLTbaseCompileInfo(date, time);
108 if (!date) date="unknown";
109 if (!time) time="unknown";
110 HLTInfo("%s build on %s (%s)", PACKAGE_STRING, date, time);
112 HLTInfo("ALICE High Level Trigger build on %s (%s) (embedded AliRoot build)", __DATE__, __TIME__);
117 Int_t AliHLTComponentHandler::RegisterComponent(AliHLTComponent* pSample)
119 // see header file for class documentation
122 if (FindComponent(pSample->GetComponentID())==NULL) {
123 iResult=InsertComponent(pSample);
125 HLTInfo("component %s registered", pSample->GetComponentID());
128 // component already registered
129 HLTDebug("component %s already registered, skipped", pSample->GetComponentID());
138 int AliHLTComponentHandler::DeregisterComponent( const char* componentID )
140 // see header file for class documentation
144 HLTWarning("not yet implemented, please notify the developers if you need this function");
151 Int_t AliHLTComponentHandler::ScheduleRegister(AliHLTComponent* pSample)
153 // see header file for class documentation
156 fScheduleList.push_back(pSample);
163 int AliHLTComponentHandler::CreateComponent(const char* componentID, void* pEnvParam, int argc, const char** argv, AliHLTComponent*& component )
165 // see header file for class documentation
168 AliHLTComponent* pSample=FindComponent(componentID);
170 component=pSample->Spawn();
172 HLTDebug("component \"%s\" created (%p)", componentID, component);
173 if ((iResult=component->Init(&fEnvironment, pEnvParam, argc, argv))!=0) {
174 HLTError("Initialization of component \"%s\" failed with error %d", componentID, iResult);
179 HLTError("can not spawn component \"%s\"", componentID);
183 HLTWarning("can not find component \"%s\"", componentID);
192 Int_t AliHLTComponentHandler::FindComponentIndex(const char* componentID)
194 // see header file for class documentation
197 vector<AliHLTComponent*>::iterator element=fComponentList.begin();
198 while (element!=fComponentList.end() && iResult>=0) {
199 if (strcmp(componentID, (*element)->GetComponentID())==0) {
205 if (element==fComponentList.end()) iResult=-ENOENT;
212 AliHLTComponent* AliHLTComponentHandler::FindComponent(const char* componentID)
214 // see header file for class documentation
215 AliHLTComponent* pSample=NULL;
216 Int_t index=FindComponentIndex(componentID);
218 pSample=(AliHLTComponent*)fComponentList.at(index);
223 Int_t AliHLTComponentHandler::InsertComponent(AliHLTComponent* pSample)
225 // see header file for class documentation
228 fComponentList.push_back(pSample);
235 void AliHLTComponentHandler::List()
237 // see header file for class documentation
238 vector<AliHLTComponent*>::iterator element=fComponentList.begin();
240 while (element!=fComponentList.end()) {
241 HLTInfo("%d. %s", index++, (*element++)->GetComponentID());
245 void AliHLTComponentHandler::SetEnvironment(AliHLTComponentEnvironment* pEnv)
247 // see header file for class documentation
249 memcpy(&fEnvironment, pEnv, sizeof(AliHLTComponentEnvironment));
250 if (fEnvironment.fLoggingFunc) {
251 // the AliHLTLogging::Init method also sets the stream output
252 // and notification handler to AliLog. This should only be done
253 // if the logging environment contains a logging function
255 AliHLTLogging::Init(fEnvironment.fLoggingFunc);
260 int AliHLTComponentHandler::LoadLibrary( const char* libraryPath )
262 // see header file for class documentation
265 AliHLTComponent::SetGlobalComponentHandler(this);
266 AliHLTLibHandle hLib;
267 const char* loadtype="";
269 // use interface to the dynamic linking loader
270 hLib.fHandle=dlopen(libraryPath, RTLD_NOW);
273 // use ROOT dynamic loader
274 // check if the library was already loaded, as Load returns
275 // 'failure' if the library was already loaded
276 AliHLTLibHandle* pLib=FindLibrary(libraryPath);
278 int* pRootHandle=reinterpret_cast<int*>(pLib->fHandle);
280 HLTDebug("instance %d of library %s loaded", (*pRootHandle), libraryPath);
281 hLib.fHandle=pRootHandle;
284 if (hLib.fHandle==NULL && gSystem->Load(libraryPath)==0) {
285 int* pRootHandle=new int;
286 if (pRootHandle) *pRootHandle=1;
287 hLib.fHandle=pRootHandle;
288 //HLTDebug("library %s loaded via gSystem", libraryPath);
291 #endif //HAVE_DLFCN_H
292 if (hLib.fHandle!=NULL) {
293 // create TString object to store library path and use pointer as handle
294 hLib.fName=new TString(libraryPath);
295 HLTInfo("library %s loaded (%s)", libraryPath, loadtype);
296 fLibraryList.insert(fLibraryList.begin(), hLib);
297 typedef void (*CompileInfo)( char*& date, char*& time);
298 CompileInfo fctInfo=(CompileInfo)FindSymbol(libraryPath, "CompileInfo");
302 (*fctInfo)(date, time);
303 if (!date) date="unknown";
304 if (!time) time="unknown";
305 HLTInfo("build on %s (%s)", date, time);
307 HLTInfo("no build info available (possible AliRoot embedded build)");
309 iResult=RegisterScheduledComponents();
311 HLTError("can not load library %s", libraryPath);
313 HLTError("dlopen error: %s", dlerror());
314 #endif //HAVE_DLFCN_H
321 AliHLTComponent::UnsetGlobalComponentHandler();
328 int AliHLTComponentHandler::UnloadLibrary( const char* libraryPath )
330 // see header file for class documentation
333 vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
334 while (element!=fLibraryList.end()) {
335 TString* pName=reinterpret_cast<TString*>((*element).fName);
336 if (pName->CompareTo(libraryPath)==0) {
337 UnloadLibrary(*element);
338 fLibraryList.erase(element);
349 int AliHLTComponentHandler::UnloadLibrary(AliHLTComponentHandler::AliHLTLibHandle &handle)
351 // see header file for class documentation
353 fgAliLoggingFunc=NULL;
354 TString* pName=reinterpret_cast<TString*>(handle.fName);
356 dlclose(handle.fHandle);
358 int* pCount=reinterpret_cast<int*>(handle.fHandle);
359 if (--(*pCount)==0) {
361 /** Matthias 26.04.2007
362 * I spent about a week to investigate a bug which seems to be in ROOT.
363 * Under certain circumstances, TSystem::Unload crashes. The crash occured
364 * for the first time, when libAliHLTUtil was loaded from AliHLTSystem right
365 * after the ComponentHandler was created. It does not occur when dlopen is
367 * It has most likely to do with the garbage collection and automatic
368 * cleanup in ROOT. The crash occurs when ROOT is terminated and before
369 * an instance of AliHLTSystem was created.
370 * root [0] AliHLTSystem gHLT
371 * It does not occur when the instance was created dynamically (but not even
373 * root [0] AliHLTSystem* gHLT=new AliHLTSystem
375 * For that reason, the libraries are not unloaded here, even though there
376 * will be memory leaks.
377 gSystem->Unload(pName->Data());
381 HLTError("missing library name, can not unload");
385 #endif //HAVE_DLFCN_H
389 HLTDebug("unload library %s", pName->Data());
392 HLTWarning("missing name for unloaded library");
398 int AliHLTComponentHandler::UnloadLibraries()
400 // see header file for class documentation
402 vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
403 while (element!=fLibraryList.end()) {
404 UnloadLibrary(*element);
405 fLibraryList.erase(element);
406 element=fLibraryList.begin();
411 void* AliHLTComponentHandler::FindSymbol(const char* library, const char* symbol)
413 // see header file for class documentation
414 AliHLTLibHandle* hLib=FindLibrary(library);
415 if (hLib==NULL) return NULL;
418 pFunc=dlsym(hLib->fHandle, symbol);
420 TString* name=reinterpret_cast<TString*>(hLib->fName);
421 pFunc=gSystem->DynFindSymbol(name->Data(), symbol);
426 AliHLTComponentHandler::AliHLTLibHandle* AliHLTComponentHandler::FindLibrary(const char* library)
428 // see header file for class documentation
429 AliHLTLibHandle* hLib=NULL;
430 vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
431 while (element!=fLibraryList.end()) {
432 TString* name=reinterpret_cast<TString*>((*element).fName);
433 if (name->CompareTo(library)==0) {
442 int AliHLTComponentHandler::AddStandardComponents()
444 // see header file for class documentation
446 AliHLTComponent::SetGlobalComponentHandler(this);
447 // fStandardList.push_back(new AliHLTFilePublisher);
448 // fStandardList.push_back(new AliHLTFileWriter);
449 // fStandardList.push_back(new AliHLTRootFilePublisherComponent);
450 // fStandardList.push_back(new AliHLTRootFileWriterComponent);
451 AliHLTComponent::UnsetGlobalComponentHandler();
452 iResult=RegisterScheduledComponents();
456 int AliHLTComponentHandler::RegisterScheduledComponents()
458 // see header file for class documentation
460 vector<AliHLTComponent*>::iterator element=fScheduleList.begin();
462 while (element!=fScheduleList.end()) {
463 iLocalResult=RegisterComponent(*element);
464 if (iResult==0) iResult=iLocalResult;
465 fScheduleList.erase(element);
466 element=fScheduleList.begin();
471 int AliHLTComponentHandler::DeleteStandardComponents()
473 // see header file for class documentation
475 vector<AliHLTComponent*>::iterator element=fStandardList.begin();
476 while (element!=fStandardList.end()) {
477 //DeregisterComponent((*element)->GetComponentID());
479 fStandardList.erase(element);
480 element=fStandardList.begin();