]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/AliHLTComponentHandler.cxx
Getting rid of trivial warnings.
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTComponentHandler.cxx
CommitLineData
f23a6e1a 1// $Id$
2
3/**************************************************************************
9be2600f 4 * This file is property of and copyright by the ALICE HLT Project *
5 * ALICE Experiment at CERN, All rights reserved. *
f23a6e1a 6 * *
9be2600f 7 * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 * Timm Steinbeck <timm@kip.uni-heidelberg.de> *
9 * for The ALICE HLT Project. *
f23a6e1a 10 * *
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 **************************************************************************/
19
b22e91eb 20/** @file AliHLTComponentHandler.cxx
21 @author Matthias Richter, Timm Steinbeck
22 @date
23 @brief Implementation of HLT component handler. */
f23a6e1a 24
7bcd6cad 25// see header file for class documentation
26// or
27// refer to README to build package
28// or
29// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
30
0c0c9d99 31#if __GNUC__>= 3
f23a6e1a 32using namespace std;
33#endif
53feaef5 34//#undef HAVE_DLFCN_H
35#ifdef HAVE_DLFCN_H
f23a6e1a 36#include <dlfcn.h>
53feaef5 37#else
38//#include <Riostream.h>
39#include <TSystem.h>
40#endif //HAVE_DLFCN_H
5df0cbb9 41//#include "AliHLTStdIncludes.h"
f23a6e1a 42#include "AliHLTComponentHandler.h"
43#include "AliHLTComponent.h"
44#include "AliHLTDataTypes.h"
f3506ea2 45#include "AliHLTModuleAgent.h"
5df0cbb9 46#include "TString.h"
f23a6e1a 47
b22e91eb 48/** ROOT macro for the implementation of ROOT specific class methods */
f23a6e1a 49ClassImp(AliHLTComponentHandler)
50
51AliHLTComponentHandler::AliHLTComponentHandler()
85869391 52 :
53 fComponentList(),
54 fScheduleList(),
55 fLibraryList(),
9ce4bf4a 56 fEnvironment(),
f3506ea2 57 fOwnedComponents()
f23a6e1a 58{
70ed7d01 59 // see header file for class documentation
60 // or
61 // refer to README to build package
62 // or
63 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
85869391 64 memset(&fEnvironment, 0, sizeof(AliHLTComponentEnvironment));
9ce4bf4a 65 AddStandardComponents();
f23a6e1a 66}
67
3cde846d 68AliHLTComponentHandler::AliHLTComponentHandler(AliHLTComponentEnvironment* pEnv)
69 :
298ef463 70 AliHLTLogging(),
3cde846d 71 fComponentList(),
72 fScheduleList(),
73 fLibraryList(),
74 fEnvironment(),
f3506ea2 75 fOwnedComponents()
3cde846d 76{
70ed7d01 77 // see header file for class documentation
3cde846d 78 if (pEnv) {
79 memcpy(&fEnvironment, pEnv, sizeof(AliHLTComponentEnvironment));
fa274626 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
84 // for redirection
85 AliHLTLogging::Init(pEnv->fLoggingFunc);
86 }
f3506ea2 87 } else {
3cde846d 88 memset(&fEnvironment, 0, sizeof(AliHLTComponentEnvironment));
f3506ea2 89 }
90 //#ifndef __DEBUG
91 //SetLocalLoggingLevel(kHLTLogError);
92 //#else
93 //SetLocalLoggingLevel(kHLTLogInfo);
94 //#endif
95
3cde846d 96 AddStandardComponents();
97}
98
f23a6e1a 99AliHLTComponentHandler::~AliHLTComponentHandler()
100{
70ed7d01 101 // see header file for class documentation
cbd84228 102 DeleteOwnedComponents();
a742f6f8 103 UnloadLibraries();
f23a6e1a 104}
105
fa760045 106int AliHLTComponentHandler::AnnounceVersion()
107{
70ed7d01 108 // see header file for class documentation
fa760045 109 int iResult=0;
110#ifdef PACKAGE_STRING
111 void HLTbaseCompileInfo( char*& date, char*& time);
112 char* date="";
113 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);
118#else
a742f6f8 119 HLTInfo("ALICE High Level Trigger build on %s (%s) (embedded AliRoot build)", __DATE__, __TIME__);
fa760045 120#endif
121 return iResult;
122}
123
f3506ea2 124Int_t AliHLTComponentHandler::AddComponent(AliHLTComponent* pSample)
125{
126 // see header file for class documentation
127 Int_t iResult=0;
cbd84228 128 if (pSample==NULL) return -EINVAL;
f3506ea2 129 if ((iResult=RegisterComponent(pSample))>=0) {
cbd84228 130 //HLTDebug("sample %s (%p) managed by handler", pSample->GetComponentID(), pSample);
f3506ea2 131 fOwnedComponents.push_back(pSample);
132 }
133 return iResult;
134}
135
f23a6e1a 136Int_t AliHLTComponentHandler::RegisterComponent(AliHLTComponent* pSample)
137{
70ed7d01 138 // see header file for class documentation
f23a6e1a 139 Int_t iResult=0;
140 if (pSample) {
141 if (FindComponent(pSample->GetComponentID())==NULL) {
142 iResult=InsertComponent(pSample);
143 if (iResult>=0) {
85465857 144 HLTInfo("component %s registered", pSample->GetComponentID());
f23a6e1a 145 }
146 } else {
147 // component already registered
fa760045 148 HLTDebug("component %s already registered, skipped", pSample->GetComponentID());
f23a6e1a 149 iResult=-EEXIST;
150 }
151 } else {
152 iResult=-EINVAL;
153 }
154 return iResult;
155}
156
157int AliHLTComponentHandler::DeregisterComponent( const char* componentID )
158{
70ed7d01 159 // see header file for class documentation
5df0cbb9 160
53feaef5 161 int iResult=0;
162 if (componentID) {
5df0cbb9 163 HLTWarning("not yet implemented, please notify the developers if you need this function");
53feaef5 164 } else {
165 iResult=-EINVAL;
166 }
167 return iResult;
f23a6e1a 168}
169
170Int_t AliHLTComponentHandler::ScheduleRegister(AliHLTComponent* pSample)
171{
70ed7d01 172 // see header file for class documentation
f23a6e1a 173 Int_t iResult=0;
174 if (pSample) {
175 fScheduleList.push_back(pSample);
176 } else {
177 iResult=-EINVAL;
178 }
179 return iResult;
180}
181
2d7ff710 182int AliHLTComponentHandler::CreateComponent(const char* componentID, void* pEnvParam, int argc, const char** argv, AliHLTComponent*& component )
f23a6e1a 183{
70ed7d01 184 // see header file for class documentation
f23a6e1a 185 int iResult=0;
186 if (componentID) {
187 AliHLTComponent* pSample=FindComponent(componentID);
188 if (pSample!=NULL) {
189 component=pSample->Spawn();
190 if (component) {
85465857 191 HLTDebug("component \"%s\" created (%p)", componentID, component);
2d7ff710 192 if ((iResult=component->Init(&fEnvironment, pEnvParam, argc, argv))!=0) {
84645eb0 193 HLTError("Initialization of component \"%s\" failed with error %d", componentID, iResult);
194 delete component;
195 component=NULL;
196 }
5ec8e281 197 } else {
85465857 198 HLTError("can not spawn component \"%s\"", componentID);
5ec8e281 199 iResult=-ENOENT;
f23a6e1a 200 }
5ec8e281 201 } else {
85465857 202 HLTWarning("can not find component \"%s\"", componentID);
5ec8e281 203 iResult=-ENOENT;
f23a6e1a 204 }
205 } else {
206 iResult=-EINVAL;
207 }
208 return iResult;
209}
210
db16520a 211Int_t AliHLTComponentHandler::FindComponentIndex(const char* componentID)
f23a6e1a 212{
70ed7d01 213 // see header file for class documentation
f23a6e1a 214 Int_t iResult=0;
215 if (componentID) {
7bcd6cad 216 AliHLTComponentPList::iterator element=fComponentList.begin();
f23a6e1a 217 while (element!=fComponentList.end() && iResult>=0) {
218 if (strcmp(componentID, (*element)->GetComponentID())==0) {
219 break;
220 }
221 element++;
222 iResult++;
223 }
224 if (element==fComponentList.end()) iResult=-ENOENT;
225 } else {
226 iResult=-EINVAL;
227 }
228 return iResult;
229}
230
db16520a 231AliHLTComponent* AliHLTComponentHandler::FindComponent(const char* componentID)
f23a6e1a 232{
70ed7d01 233 // see header file for class documentation
f23a6e1a 234 AliHLTComponent* pSample=NULL;
235 Int_t index=FindComponentIndex(componentID);
236 if (index>=0) {
237 pSample=(AliHLTComponent*)fComponentList.at(index);
238 }
239 return pSample;
240}
241
242Int_t AliHLTComponentHandler::InsertComponent(AliHLTComponent* pSample)
243{
70ed7d01 244 // see header file for class documentation
f23a6e1a 245 Int_t iResult=0;
246 if (pSample!=NULL) {
247 fComponentList.push_back(pSample);
248 } else {
249 iResult=-EINVAL;
250 }
251 return iResult;
252}
253
70ed7d01 254void AliHLTComponentHandler::List()
255{
256 // see header file for class documentation
7bcd6cad 257 AliHLTComponentPList::iterator element=fComponentList.begin();
f23a6e1a 258 int index=0;
259 while (element!=fComponentList.end()) {
85465857 260 HLTInfo("%d. %s", index++, (*element++)->GetComponentID());
f23a6e1a 261 }
262}
263
f3506ea2 264int AliHLTComponentHandler::HasOutputData( const char* componentID)
265{
266 // see header file for class documentation
267 int iResult=0;
268 AliHLTComponent* pSample=FindComponent(componentID);
269 if (pSample) {
270 AliHLTComponent::TComponentType ct=AliHLTComponent::kUnknown;
271 ct=pSample->GetComponentType();
272 iResult=(ct==AliHLTComponent::kSource || ct==AliHLTComponent::kProcessor);
273 } else {
274 iResult=-ENOENT;
275 }
276 return iResult;
277}
278
70ed7d01 279void AliHLTComponentHandler::SetEnvironment(AliHLTComponentEnvironment* pEnv)
280{
281 // see header file for class documentation
f23a6e1a 282 if (pEnv) {
283 memcpy(&fEnvironment, pEnv, sizeof(AliHLTComponentEnvironment));
fa274626 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
288 // for redirection
289 AliHLTLogging::Init(fEnvironment.fLoggingFunc);
290 }
f23a6e1a 291 }
292}
293
dba03d72 294AliHLTComponentHandler::TLibraryMode AliHLTComponentHandler::SetLibraryMode(TLibraryMode mode)
295{
296 // see header file for class documentation
297 TLibraryMode old=fLibraryMode;
298 fLibraryMode=mode;
299 return old;
300}
301
f3506ea2 302int AliHLTComponentHandler::LoadLibrary( const char* libraryPath, int bActivateAgents)
f23a6e1a 303{
70ed7d01 304 // see header file for class documentation
f23a6e1a 305 int iResult=0;
306 if (libraryPath) {
f3506ea2 307 // first activate all agents which are already loaded
308 if (bActivateAgents) ActivateAgents();
309
310 // set the global component handler for static component registration
f23a6e1a 311 AliHLTComponent::SetGlobalComponentHandler(this);
f3506ea2 312
c215072c 313 AliHLTLibHandle hLib;
85f0cede 314 const char* loadtype="";
53feaef5 315#ifdef HAVE_DLFCN_H
316 // use interface to the dynamic linking loader
f3506ea2 317 try {
318 hLib.fHandle=dlopen(libraryPath, RTLD_NOW);
319 loadtype="dlopen";
320 }
321 catch (...) {
322 // error message printed further down
323 loadtype="dlopen exeption";
324 }
53feaef5 325#else
326 // use ROOT dynamic loader
c215072c 327 // check if the library was already loaded, as Load returns
328 // 'failure' if the library was already loaded
f3506ea2 329 try {
85f0cede 330 AliHLTLibHandle* pLib=FindLibrary(libraryPath);
331 if (pLib) {
5df0cbb9 332 int* pRootHandle=reinterpret_cast<int*>(pLib->fHandle);
c215072c 333 (*pRootHandle)++;
334 HLTDebug("instance %d of library %s loaded", (*pRootHandle), libraryPath);
5df0cbb9 335 hLib.fHandle=pRootHandle;
c215072c 336 }
337
5df0cbb9 338 if (hLib.fHandle==NULL && gSystem->Load(libraryPath)==0) {
c215072c 339 int* pRootHandle=new int;
340 if (pRootHandle) *pRootHandle=1;
5df0cbb9 341 hLib.fHandle=pRootHandle;
85f0cede 342 //HLTDebug("library %s loaded via gSystem", libraryPath);
53feaef5 343 }
85f0cede 344 loadtype="gSystem";
f3506ea2 345 }
346 catch (...) {
347 // error message printed further down
348 loadtype="gSystem exeption";
349 }
53feaef5 350#endif //HAVE_DLFCN_H
5df0cbb9 351 if (hLib.fHandle!=NULL) {
c215072c 352 // create TString object to store library path and use pointer as handle
5df0cbb9 353 hLib.fName=new TString(libraryPath);
dba03d72 354 hLib.fMode=fLibraryMode;
355 HLTInfo("library %s loaded (%s%s)", libraryPath, hLib.fMode==kStatic?"persistent, ":"", loadtype);
c215072c 356 fLibraryList.insert(fLibraryList.begin(), hLib);
842fd76a 357 typedef void (*CompileInfo)( char*& date, char*& time);
358 CompileInfo fctInfo=(CompileInfo)FindSymbol(libraryPath, "CompileInfo");
359 if (fctInfo) {
360 char* date="";
361 char* time="";
362 (*fctInfo)(date, time);
363 if (!date) date="unknown";
364 if (!time) time="unknown";
365 HLTInfo("build on %s (%s)", date, time);
366 } else {
367 HLTInfo("no build info available (possible AliRoot embedded build)");
368 }
f3506ea2 369
370 // static registration of components when library is loaded
9ce4bf4a 371 iResult=RegisterScheduledComponents();
f3506ea2 372
f23a6e1a 373 } else {
f3506ea2 374 HLTError("can not load library %s (%s)", libraryPath, loadtype);
53feaef5 375#ifdef HAVE_DLFCN_H
85465857 376 HLTError("dlopen error: %s", dlerror());
53feaef5 377#endif //HAVE_DLFCN_H
0fe88043 378#ifdef __APPLE__
379 iResult=-EFTYPE;
380#else
f23a6e1a 381 iResult=-ELIBACC;
0fe88043 382#endif
f23a6e1a 383 }
2bbbadd1 384 AliHLTComponent::UnsetGlobalComponentHandler();
f3506ea2 385
386 if (iResult>=0) {
387 // alternative dynamic registration by library agents
388 // !!! has to be done after UnsetGlobalComponentHandler
389 if (bActivateAgents) ActivateAgents();
390 }
391
f23a6e1a 392 } else {
393 iResult=-EINVAL;
394 }
395 return iResult;
396}
397
398int AliHLTComponentHandler::UnloadLibrary( const char* libraryPath )
399{
70ed7d01 400 // see header file for class documentation
f23a6e1a 401 int iResult=0;
53feaef5 402 if (libraryPath) {
a742f6f8 403 vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
404 while (element!=fLibraryList.end()) {
5df0cbb9 405 TString* pName=reinterpret_cast<TString*>((*element).fName);
a742f6f8 406 if (pName->CompareTo(libraryPath)==0) {
407 UnloadLibrary(*element);
408 fLibraryList.erase(element);
409 break;
410 }
411 element++;
412 }
53feaef5 413 } else {
414 iResult=-EINVAL;
415 }
f23a6e1a 416 return iResult;
417}
418
a742f6f8 419int AliHLTComponentHandler::UnloadLibrary(AliHLTComponentHandler::AliHLTLibHandle &handle)
f23a6e1a 420{
70ed7d01 421 // see header file for class documentation
f23a6e1a 422 int iResult=0;
a742f6f8 423 fgAliLoggingFunc=NULL;
5df0cbb9 424 TString* pName=reinterpret_cast<TString*>(handle.fName);
dba03d72 425 if (handle.fMode!=kStatic) {
53feaef5 426#ifdef HAVE_DLFCN_H
f3506ea2 427 try {
428 dlclose(handle.fHandle);
429 }
430 catch (...) {
431 HLTError("exeption caught during dlclose of library %s", pName!=NULL?pName->Data():"");
432 }
53feaef5 433#else
5df0cbb9 434 int* pCount=reinterpret_cast<int*>(handle.fHandle);
a742f6f8 435 if (--(*pCount)==0) {
c215072c 436 if (pName) {
a7222a6d 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
442 * used.
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
448 * deleted)
449 * root [0] AliHLTSystem* gHLT=new AliHLTSystem
450 *
451 * For that reason, the libraries are not unloaded here, even though there
452 * will be memory leaks.
a742f6f8 453 gSystem->Unload(pName->Data());
a7222a6d 454 */
a742f6f8 455 }
456 else {
457 HLTError("missing library name, can not unload");
c215072c 458 }
a742f6f8 459 delete pCount;
460 }
461#endif //HAVE_DLFCN_H
a742f6f8 462 if (pName) {
463 HLTDebug("unload library %s", pName->Data());
a742f6f8 464 } else {
465 HLTWarning("missing name for unloaded library");
466 }
dba03d72 467 }
468 handle.fName=NULL;
469 handle.fHandle=NULL;
470 if (pName) {
471 delete pName;
472 }
a742f6f8 473 pName=NULL;
474 return iResult;
475}
476
477int AliHLTComponentHandler::UnloadLibraries()
478{
479 // see header file for class documentation
480 int iResult=0;
481 vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
482 while (element!=fLibraryList.end()) {
483 UnloadLibrary(*element);
c215072c 484 fLibraryList.erase(element);
485 element=fLibraryList.begin();
f23a6e1a 486 }
487 return iResult;
488}
9ce4bf4a 489
85f0cede 490void* AliHLTComponentHandler::FindSymbol(const char* library, const char* symbol)
491{
492 // see header file for class documentation
493 AliHLTLibHandle* hLib=FindLibrary(library);
494 if (hLib==NULL) return NULL;
495 void* pFunc=NULL;
496#ifdef HAVE_DLFCN_H
5df0cbb9 497 pFunc=dlsym(hLib->fHandle, symbol);
85f0cede 498#else
5df0cbb9 499 TString* name=reinterpret_cast<TString*>(hLib->fName);
85f0cede 500 pFunc=gSystem->DynFindSymbol(name->Data(), symbol);
501#endif
502 return pFunc;
503}
504
505AliHLTComponentHandler::AliHLTLibHandle* AliHLTComponentHandler::FindLibrary(const char* library)
506{
507 // see header file for class documentation
508 AliHLTLibHandle* hLib=NULL;
509 vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
510 while (element!=fLibraryList.end()) {
5df0cbb9 511 TString* name=reinterpret_cast<TString*>((*element).fName);
85f0cede 512 if (name->CompareTo(library)==0) {
513 hLib=&(*element);
514 break;
515 }
516 element++;
517 }
518 return hLib;
519}
520
9ce4bf4a 521int AliHLTComponentHandler::AddStandardComponents()
522{
70ed7d01 523 // see header file for class documentation
9ce4bf4a 524 int iResult=0;
525 AliHLTComponent::SetGlobalComponentHandler(this);
9ce4bf4a 526 AliHLTComponent::UnsetGlobalComponentHandler();
527 iResult=RegisterScheduledComponents();
528 return iResult;
529}
530
531int AliHLTComponentHandler::RegisterScheduledComponents()
532{
70ed7d01 533 // see header file for class documentation
9ce4bf4a 534 int iResult=0;
7bcd6cad 535 AliHLTComponentPList::iterator element=fScheduleList.begin();
9ce4bf4a 536 int iLocalResult=0;
537 while (element!=fScheduleList.end()) {
538 iLocalResult=RegisterComponent(*element);
539 if (iResult==0) iResult=iLocalResult;
540 fScheduleList.erase(element);
541 element=fScheduleList.begin();
542 }
543 return iResult;
544}
545
f3506ea2 546int AliHLTComponentHandler::ActivateAgents(const AliHLTModuleAgent** blackList, int size)
547{
548 // see header file for class documentation
549 int iResult=0;
550 AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
551 while (pAgent && iResult>=0) {
552 if (blackList) {
553 int i=0;
554 for (; i<size; i++) {
555 if (blackList[i]==pAgent) break;
556 }
557 if (i<size) {
558 // this agent was in the list
559 pAgent=AliHLTModuleAgent::GetNextAgent();
560 continue;
561 }
562 }
563
564 pAgent->ActivateComponentHandler(this);
565 pAgent=AliHLTModuleAgent::GetNextAgent();
566 }
567 return iResult;
568}
569
cbd84228 570int AliHLTComponentHandler::DeleteOwnedComponents()
9ce4bf4a 571{
70ed7d01 572 // see header file for class documentation
9ce4bf4a 573 int iResult=0;
7bcd6cad 574 AliHLTComponentPList::iterator element=fOwnedComponents.begin();
f3506ea2 575 while (element!=fOwnedComponents.end()) {
5df0cbb9 576 //DeregisterComponent((*element)->GetComponentID());
cbd84228 577 try {
578 delete *element;
579 }
580 catch (...) {
581 HLTError("delete managed sample %p", *element);
582 }
f3506ea2 583 fOwnedComponents.erase(element);
584 element=fOwnedComponents.begin();
9ce4bf4a 585 }
586 return iResult;
587}