]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/AliHLTComponentHandler.cxx
Coding violations fixed (first bunch!)
[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
f3506ea2 322 try {
323 hLib.fHandle=dlopen(libraryPath, RTLD_NOW);
324 loadtype="dlopen";
325 }
326 catch (...) {
327 // error message printed further down
328 loadtype="dlopen exeption";
329 }
53feaef5 330#else
331 // use ROOT dynamic loader
c215072c 332 // check if the library was already loaded, as Load returns
333 // 'failure' if the library was already loaded
f3506ea2 334 try {
85f0cede 335 AliHLTLibHandle* pLib=FindLibrary(libraryPath);
336 if (pLib) {
5df0cbb9 337 int* pRootHandle=reinterpret_cast<int*>(pLib->fHandle);
c215072c 338 (*pRootHandle)++;
339 HLTDebug("instance %d of library %s loaded", (*pRootHandle), libraryPath);
5df0cbb9 340 hLib.fHandle=pRootHandle;
c215072c 341 }
342
5df0cbb9 343 if (hLib.fHandle==NULL && gSystem->Load(libraryPath)==0) {
c215072c 344 int* pRootHandle=new int;
345 if (pRootHandle) *pRootHandle=1;
5df0cbb9 346 hLib.fHandle=pRootHandle;
85f0cede 347 //HLTDebug("library %s loaded via gSystem", libraryPath);
53feaef5 348 }
85f0cede 349 loadtype="gSystem";
f3506ea2 350 }
351 catch (...) {
352 // error message printed further down
353 loadtype="gSystem exeption";
354 }
53feaef5 355#endif //HAVE_DLFCN_H
5df0cbb9 356 if (hLib.fHandle!=NULL) {
c215072c 357 // create TString object to store library path and use pointer as handle
5df0cbb9 358 hLib.fName=new TString(libraryPath);
dba03d72 359 hLib.fMode=fLibraryMode;
b2065764 360 HLTImportant("library %s loaded (%s%s)", libraryPath, hLib.fMode==kStatic?"persistent, ":"", loadtype);
c215072c 361 fLibraryList.insert(fLibraryList.begin(), hLib);
842fd76a 362 typedef void (*CompileInfo)( char*& date, char*& time);
363 CompileInfo fctInfo=(CompileInfo)FindSymbol(libraryPath, "CompileInfo");
364 if (fctInfo) {
365 char* date="";
366 char* time="";
367 (*fctInfo)(date, time);
368 if (!date) date="unknown";
369 if (!time) time="unknown";
b2065764 370 HLTImportant("build on %s (%s)", date, time);
842fd76a 371 } else {
b2065764 372 HLTImportant("no build info available (possible AliRoot embedded build)");
842fd76a 373 }
f3506ea2 374
375 // static registration of components when library is loaded
9ce4bf4a 376 iResult=RegisterScheduledComponents();
f3506ea2 377
f23a6e1a 378 } else {
f3506ea2 379 HLTError("can not load library %s (%s)", libraryPath, loadtype);
53feaef5 380#ifdef HAVE_DLFCN_H
85465857 381 HLTError("dlopen error: %s", dlerror());
53feaef5 382#endif //HAVE_DLFCN_H
0fe88043 383#ifdef __APPLE__
384 iResult=-EFTYPE;
385#else
f23a6e1a 386 iResult=-ELIBACC;
0fe88043 387#endif
f23a6e1a 388 }
2bbbadd1 389 AliHLTComponent::UnsetGlobalComponentHandler();
f3506ea2 390
391 if (iResult>=0) {
392 // alternative dynamic registration by library agents
393 // !!! has to be done after UnsetGlobalComponentHandler
394 if (bActivateAgents) ActivateAgents();
395 }
396
f23a6e1a 397 } else {
398 iResult=-EINVAL;
399 }
400 return iResult;
401}
402
403int AliHLTComponentHandler::UnloadLibrary( const char* libraryPath )
404{
70ed7d01 405 // see header file for class documentation
f23a6e1a 406 int iResult=0;
53feaef5 407 if (libraryPath) {
a742f6f8 408 vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
409 while (element!=fLibraryList.end()) {
5df0cbb9 410 TString* pName=reinterpret_cast<TString*>((*element).fName);
a742f6f8 411 if (pName->CompareTo(libraryPath)==0) {
412 UnloadLibrary(*element);
413 fLibraryList.erase(element);
414 break;
415 }
416 element++;
417 }
53feaef5 418 } else {
419 iResult=-EINVAL;
420 }
f23a6e1a 421 return iResult;
422}
423
a742f6f8 424int AliHLTComponentHandler::UnloadLibrary(AliHLTComponentHandler::AliHLTLibHandle &handle)
f23a6e1a 425{
70ed7d01 426 // see header file for class documentation
f23a6e1a 427 int iResult=0;
a742f6f8 428 fgAliLoggingFunc=NULL;
5df0cbb9 429 TString* pName=reinterpret_cast<TString*>(handle.fName);
dba03d72 430 if (handle.fMode!=kStatic) {
53feaef5 431#ifdef HAVE_DLFCN_H
f3506ea2 432 try {
433 dlclose(handle.fHandle);
434 }
435 catch (...) {
436 HLTError("exeption caught during dlclose of library %s", pName!=NULL?pName->Data():"");
437 }
53feaef5 438#else
5df0cbb9 439 int* pCount=reinterpret_cast<int*>(handle.fHandle);
a742f6f8 440 if (--(*pCount)==0) {
c215072c 441 if (pName) {
a7222a6d 442 /** Matthias 26.04.2007
443 * I spent about a week to investigate a bug which seems to be in ROOT.
444 * Under certain circumstances, TSystem::Unload crashes. The crash occured
445 * for the first time, when libAliHLTUtil was loaded from AliHLTSystem right
446 * after the ComponentHandler was created. It does not occur when dlopen is
447 * used.
448 * It has most likely to do with the garbage collection and automatic
449 * cleanup in ROOT. The crash occurs when ROOT is terminated and before
450 * an instance of AliHLTSystem was created.
451 * root [0] AliHLTSystem gHLT
452 * It does not occur when the instance was created dynamically (but not even
453 * deleted)
454 * root [0] AliHLTSystem* gHLT=new AliHLTSystem
455 *
456 * For that reason, the libraries are not unloaded here, even though there
457 * will be memory leaks.
a742f6f8 458 gSystem->Unload(pName->Data());
a7222a6d 459 */
a742f6f8 460 }
461 else {
462 HLTError("missing library name, can not unload");
c215072c 463 }
a742f6f8 464 delete pCount;
465 }
466#endif //HAVE_DLFCN_H
a742f6f8 467 if (pName) {
468 HLTDebug("unload library %s", pName->Data());
a742f6f8 469 } else {
470 HLTWarning("missing name for unloaded library");
471 }
dba03d72 472 }
473 handle.fName=NULL;
474 handle.fHandle=NULL;
475 if (pName) {
476 delete pName;
477 }
a742f6f8 478 pName=NULL;
479 return iResult;
480}
481
482int AliHLTComponentHandler::UnloadLibraries()
483{
484 // see header file for class documentation
485 int iResult=0;
486 vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
487 while (element!=fLibraryList.end()) {
488 UnloadLibrary(*element);
c215072c 489 fLibraryList.erase(element);
490 element=fLibraryList.begin();
f23a6e1a 491 }
492 return iResult;
493}
9ce4bf4a 494
85f0cede 495void* AliHLTComponentHandler::FindSymbol(const char* library, const char* symbol)
496{
497 // see header file for class documentation
498 AliHLTLibHandle* hLib=FindLibrary(library);
499 if (hLib==NULL) return NULL;
500 void* pFunc=NULL;
501#ifdef HAVE_DLFCN_H
5df0cbb9 502 pFunc=dlsym(hLib->fHandle, symbol);
85f0cede 503#else
5df0cbb9 504 TString* name=reinterpret_cast<TString*>(hLib->fName);
85f0cede 505 pFunc=gSystem->DynFindSymbol(name->Data(), symbol);
506#endif
507 return pFunc;
508}
509
510AliHLTComponentHandler::AliHLTLibHandle* AliHLTComponentHandler::FindLibrary(const char* library)
511{
512 // see header file for class documentation
513 AliHLTLibHandle* hLib=NULL;
514 vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
515 while (element!=fLibraryList.end()) {
5df0cbb9 516 TString* name=reinterpret_cast<TString*>((*element).fName);
85f0cede 517 if (name->CompareTo(library)==0) {
518 hLib=&(*element);
519 break;
520 }
521 element++;
522 }
523 return hLib;
524}
525
9ce4bf4a 526int AliHLTComponentHandler::AddStandardComponents()
527{
70ed7d01 528 // see header file for class documentation
9ce4bf4a 529 int iResult=0;
530 AliHLTComponent::SetGlobalComponentHandler(this);
9ce4bf4a 531 AliHLTComponent::UnsetGlobalComponentHandler();
532 iResult=RegisterScheduledComponents();
533 return iResult;
534}
535
536int AliHLTComponentHandler::RegisterScheduledComponents()
537{
70ed7d01 538 // see header file for class documentation
9ce4bf4a 539 int iResult=0;
7bcd6cad 540 AliHLTComponentPList::iterator element=fScheduleList.begin();
9ce4bf4a 541 int iLocalResult=0;
542 while (element!=fScheduleList.end()) {
543 iLocalResult=RegisterComponent(*element);
544 if (iResult==0) iResult=iLocalResult;
545 fScheduleList.erase(element);
546 element=fScheduleList.begin();
547 }
548 return iResult;
549}
550
f3506ea2 551int AliHLTComponentHandler::ActivateAgents(const AliHLTModuleAgent** blackList, int size)
552{
553 // see header file for class documentation
554 int iResult=0;
555 AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
556 while (pAgent && iResult>=0) {
557 if (blackList) {
558 int i=0;
559 for (; i<size; i++) {
560 if (blackList[i]==pAgent) break;
561 }
562 if (i<size) {
563 // this agent was in the list
564 pAgent=AliHLTModuleAgent::GetNextAgent();
565 continue;
566 }
567 }
568
569 pAgent->ActivateComponentHandler(this);
570 pAgent=AliHLTModuleAgent::GetNextAgent();
571 }
572 return iResult;
573}
574
cbd84228 575int AliHLTComponentHandler::DeleteOwnedComponents()
9ce4bf4a 576{
70ed7d01 577 // see header file for class documentation
9ce4bf4a 578 int iResult=0;
7bcd6cad 579 AliHLTComponentPList::iterator element=fOwnedComponents.begin();
f3506ea2 580 while (element!=fOwnedComponents.end()) {
5df0cbb9 581 //DeregisterComponent((*element)->GetComponentID());
cbd84228 582 try {
583 delete *element;
584 }
585 catch (...) {
586 HLTError("delete managed sample %p", *element);
587 }
f3506ea2 588 fOwnedComponents.erase(element);
589 element=fOwnedComponents.begin();
9ce4bf4a 590 }
591 return iResult;
592}