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