]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/AliHLTComponentHandler.cxx
The file publisher now closes files when it is done with them during a given event...
[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
0c0c9d99 25#if __GNUC__>= 3
f23a6e1a 26using namespace std;
27#endif
53feaef5 28//#undef HAVE_DLFCN_H
29#ifdef HAVE_DLFCN_H
f23a6e1a 30#include <dlfcn.h>
53feaef5 31#else
32//#include <Riostream.h>
33#include <TSystem.h>
34#endif //HAVE_DLFCN_H
5df0cbb9 35//#include "AliHLTStdIncludes.h"
f23a6e1a 36#include "AliHLTComponentHandler.h"
37#include "AliHLTComponent.h"
38#include "AliHLTDataTypes.h"
5df0cbb9 39//#include "AliHLTSystem.h"
40#include "TString.h"
f23a6e1a 41
9ce4bf4a 42// the standard components
242bb794 43// #include "AliHLTFilePublisher.h"
a742f6f8 44// #include "AliHLTFileWriter.h"
242bb794 45// #include "AliHLTRootFilePublisherComponent.h"
46// #include "AliHLTRootFileWriterComponent.h"
9ce4bf4a 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(),
57 fStandardList()
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 :
70 fComponentList(),
71 fScheduleList(),
72 fLibraryList(),
73 fEnvironment(),
74 fStandardList()
75{
70ed7d01 76 // see header file for class documentation
3cde846d 77 if (pEnv) {
78 memcpy(&fEnvironment, pEnv, sizeof(AliHLTComponentEnvironment));
fa274626 79 if (pEnv->fLoggingFunc) {
80 // the AliHLTLogging::Init method also sets the stream output
81 // and notification handler to AliLog. This should only be done
82 // if the logging environment contains a logging function
83 // for redirection
84 AliHLTLogging::Init(pEnv->fLoggingFunc);
85 }
3cde846d 86 } else
87 memset(&fEnvironment, 0, sizeof(AliHLTComponentEnvironment));
88 AddStandardComponents();
89}
90
5df0cbb9 91AliHLTComponentHandler::AliHLTComponentHandler(const AliHLTComponentHandler&)
92 :
93 fComponentList(),
94 fScheduleList(),
95 fLibraryList(),
96 fEnvironment(),
97 fStandardList()
98{
99 // see header file for class documentation
100 HLTFatal("copy constructor untested");
101}
102
103AliHLTComponentHandler& AliHLTComponentHandler::operator=(const AliHLTComponentHandler&)
104{
105 // see header file for class documentation
106 HLTFatal("assignment operator untested");
107 return *this;
108}
109
f23a6e1a 110AliHLTComponentHandler::~AliHLTComponentHandler()
111{
70ed7d01 112 // see header file for class documentation
9ce4bf4a 113 DeleteStandardComponents();
a742f6f8 114 UnloadLibraries();
f23a6e1a 115}
116
fa760045 117int AliHLTComponentHandler::AnnounceVersion()
118{
70ed7d01 119 // see header file for class documentation
fa760045 120 int iResult=0;
121#ifdef PACKAGE_STRING
122 void HLTbaseCompileInfo( char*& date, char*& time);
123 char* date="";
124 char* time="";
125 HLTbaseCompileInfo(date, time);
126 if (!date) date="unknown";
127 if (!time) time="unknown";
128 HLTInfo("%s build on %s (%s)", PACKAGE_STRING, date, time);
129#else
a742f6f8 130 HLTInfo("ALICE High Level Trigger build on %s (%s) (embedded AliRoot build)", __DATE__, __TIME__);
fa760045 131#endif
132 return iResult;
133}
134
f23a6e1a 135Int_t AliHLTComponentHandler::RegisterComponent(AliHLTComponent* pSample)
136{
70ed7d01 137 // see header file for class documentation
f23a6e1a 138 Int_t iResult=0;
139 if (pSample) {
140 if (FindComponent(pSample->GetComponentID())==NULL) {
141 iResult=InsertComponent(pSample);
142 if (iResult>=0) {
85465857 143 HLTInfo("component %s registered", pSample->GetComponentID());
f23a6e1a 144 }
145 } else {
146 // component already registered
fa760045 147 HLTDebug("component %s already registered, skipped", pSample->GetComponentID());
f23a6e1a 148 iResult=-EEXIST;
149 }
150 } else {
151 iResult=-EINVAL;
152 }
153 return iResult;
154}
155
156int AliHLTComponentHandler::DeregisterComponent( const char* componentID )
157{
70ed7d01 158 // see header file for class documentation
5df0cbb9 159
53feaef5 160 int iResult=0;
161 if (componentID) {
5df0cbb9 162 HLTWarning("not yet implemented, please notify the developers if you need this function");
53feaef5 163 } else {
164 iResult=-EINVAL;
165 }
166 return iResult;
f23a6e1a 167}
168
169Int_t AliHLTComponentHandler::ScheduleRegister(AliHLTComponent* pSample)
170{
70ed7d01 171 // see header file for class documentation
f23a6e1a 172 Int_t iResult=0;
173 if (pSample) {
174 fScheduleList.push_back(pSample);
175 } else {
176 iResult=-EINVAL;
177 }
178 return iResult;
179}
180
2d7ff710 181int AliHLTComponentHandler::CreateComponent(const char* componentID, void* pEnvParam, int argc, const char** argv, AliHLTComponent*& component )
f23a6e1a 182{
70ed7d01 183 // see header file for class documentation
f23a6e1a 184 int iResult=0;
185 if (componentID) {
186 AliHLTComponent* pSample=FindComponent(componentID);
187 if (pSample!=NULL) {
188 component=pSample->Spawn();
189 if (component) {
85465857 190 HLTDebug("component \"%s\" created (%p)", componentID, component);
2d7ff710 191 if ((iResult=component->Init(&fEnvironment, pEnvParam, argc, argv))!=0) {
84645eb0 192 HLTError("Initialization of component \"%s\" failed with error %d", componentID, iResult);
193 delete component;
194 component=NULL;
195 }
5ec8e281 196 } else {
85465857 197 HLTError("can not spawn component \"%s\"", componentID);
5ec8e281 198 iResult=-ENOENT;
f23a6e1a 199 }
5ec8e281 200 } else {
85465857 201 HLTWarning("can not find component \"%s\"", componentID);
5ec8e281 202 iResult=-ENOENT;
f23a6e1a 203 }
204 } else {
205 iResult=-EINVAL;
206 }
207 return iResult;
208}
209
db16520a 210Int_t AliHLTComponentHandler::FindComponentIndex(const char* componentID)
f23a6e1a 211{
70ed7d01 212 // see header file for class documentation
f23a6e1a 213 Int_t iResult=0;
214 if (componentID) {
215 vector<AliHLTComponent*>::iterator element=fComponentList.begin();
216 while (element!=fComponentList.end() && iResult>=0) {
217 if (strcmp(componentID, (*element)->GetComponentID())==0) {
218 break;
219 }
220 element++;
221 iResult++;
222 }
223 if (element==fComponentList.end()) iResult=-ENOENT;
224 } else {
225 iResult=-EINVAL;
226 }
227 return iResult;
228}
229
db16520a 230AliHLTComponent* AliHLTComponentHandler::FindComponent(const char* componentID)
f23a6e1a 231{
70ed7d01 232 // see header file for class documentation
f23a6e1a 233 AliHLTComponent* pSample=NULL;
234 Int_t index=FindComponentIndex(componentID);
235 if (index>=0) {
236 pSample=(AliHLTComponent*)fComponentList.at(index);
237 }
238 return pSample;
239}
240
241Int_t AliHLTComponentHandler::InsertComponent(AliHLTComponent* pSample)
242{
70ed7d01 243 // see header file for class documentation
f23a6e1a 244 Int_t iResult=0;
245 if (pSample!=NULL) {
246 fComponentList.push_back(pSample);
247 } else {
248 iResult=-EINVAL;
249 }
250 return iResult;
251}
252
70ed7d01 253void AliHLTComponentHandler::List()
254{
255 // see header file for class documentation
f23a6e1a 256 vector<AliHLTComponent*>::iterator element=fComponentList.begin();
257 int index=0;
258 while (element!=fComponentList.end()) {
85465857 259 HLTInfo("%d. %s", index++, (*element++)->GetComponentID());
f23a6e1a 260 }
261}
262
70ed7d01 263void AliHLTComponentHandler::SetEnvironment(AliHLTComponentEnvironment* pEnv)
264{
265 // see header file for class documentation
f23a6e1a 266 if (pEnv) {
267 memcpy(&fEnvironment, pEnv, sizeof(AliHLTComponentEnvironment));
fa274626 268 if (fEnvironment.fLoggingFunc) {
269 // the AliHLTLogging::Init method also sets the stream output
270 // and notification handler to AliLog. This should only be done
271 // if the logging environment contains a logging function
272 // for redirection
273 AliHLTLogging::Init(fEnvironment.fLoggingFunc);
274 }
f23a6e1a 275 }
276}
277
278int AliHLTComponentHandler::LoadLibrary( const char* libraryPath )
279{
70ed7d01 280 // see header file for class documentation
f23a6e1a 281 int iResult=0;
282 if (libraryPath) {
283 AliHLTComponent::SetGlobalComponentHandler(this);
c215072c 284 AliHLTLibHandle hLib;
85f0cede 285 const char* loadtype="";
53feaef5 286#ifdef HAVE_DLFCN_H
287 // use interface to the dynamic linking loader
5df0cbb9 288 hLib.fHandle=dlopen(libraryPath, RTLD_NOW);
85f0cede 289 loadtype="dlopen";
53feaef5 290#else
291 // use ROOT dynamic loader
c215072c 292 // check if the library was already loaded, as Load returns
293 // 'failure' if the library was already loaded
85f0cede 294 AliHLTLibHandle* pLib=FindLibrary(libraryPath);
295 if (pLib) {
5df0cbb9 296 int* pRootHandle=reinterpret_cast<int*>(pLib->fHandle);
c215072c 297 (*pRootHandle)++;
298 HLTDebug("instance %d of library %s loaded", (*pRootHandle), libraryPath);
5df0cbb9 299 hLib.fHandle=pRootHandle;
c215072c 300 }
301
5df0cbb9 302 if (hLib.fHandle==NULL && gSystem->Load(libraryPath)==0) {
c215072c 303 int* pRootHandle=new int;
304 if (pRootHandle) *pRootHandle=1;
5df0cbb9 305 hLib.fHandle=pRootHandle;
85f0cede 306 //HLTDebug("library %s loaded via gSystem", libraryPath);
53feaef5 307 }
85f0cede 308 loadtype="gSystem";
53feaef5 309#endif //HAVE_DLFCN_H
5df0cbb9 310 if (hLib.fHandle!=NULL) {
c215072c 311 // create TString object to store library path and use pointer as handle
5df0cbb9 312 hLib.fName=new TString(libraryPath);
85f0cede 313 HLTInfo("library %s loaded (%s)", libraryPath, loadtype);
c215072c 314 fLibraryList.insert(fLibraryList.begin(), hLib);
842fd76a 315 typedef void (*CompileInfo)( char*& date, char*& time);
316 CompileInfo fctInfo=(CompileInfo)FindSymbol(libraryPath, "CompileInfo");
317 if (fctInfo) {
318 char* date="";
319 char* time="";
320 (*fctInfo)(date, time);
321 if (!date) date="unknown";
322 if (!time) time="unknown";
323 HLTInfo("build on %s (%s)", date, time);
324 } else {
325 HLTInfo("no build info available (possible AliRoot embedded build)");
326 }
9ce4bf4a 327 iResult=RegisterScheduledComponents();
f23a6e1a 328 } else {
85465857 329 HLTError("can not load library %s", libraryPath);
53feaef5 330#ifdef HAVE_DLFCN_H
85465857 331 HLTError("dlopen error: %s", dlerror());
53feaef5 332#endif //HAVE_DLFCN_H
0fe88043 333#ifdef __APPLE__
334 iResult=-EFTYPE;
335#else
f23a6e1a 336 iResult=-ELIBACC;
0fe88043 337#endif
f23a6e1a 338 }
2bbbadd1 339 AliHLTComponent::UnsetGlobalComponentHandler();
f23a6e1a 340 } else {
341 iResult=-EINVAL;
342 }
343 return iResult;
344}
345
346int AliHLTComponentHandler::UnloadLibrary( const char* libraryPath )
347{
70ed7d01 348 // see header file for class documentation
f23a6e1a 349 int iResult=0;
53feaef5 350 if (libraryPath) {
a742f6f8 351 vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
352 while (element!=fLibraryList.end()) {
5df0cbb9 353 TString* pName=reinterpret_cast<TString*>((*element).fName);
a742f6f8 354 if (pName->CompareTo(libraryPath)==0) {
355 UnloadLibrary(*element);
356 fLibraryList.erase(element);
357 break;
358 }
359 element++;
360 }
53feaef5 361 } else {
362 iResult=-EINVAL;
363 }
f23a6e1a 364 return iResult;
365}
366
a742f6f8 367int AliHLTComponentHandler::UnloadLibrary(AliHLTComponentHandler::AliHLTLibHandle &handle)
f23a6e1a 368{
70ed7d01 369 // see header file for class documentation
f23a6e1a 370 int iResult=0;
a742f6f8 371 fgAliLoggingFunc=NULL;
5df0cbb9 372 TString* pName=reinterpret_cast<TString*>(handle.fName);
53feaef5 373#ifdef HAVE_DLFCN_H
5df0cbb9 374 dlclose(handle.fHandle);
53feaef5 375#else
5df0cbb9 376 int* pCount=reinterpret_cast<int*>(handle.fHandle);
a742f6f8 377 if (--(*pCount)==0) {
c215072c 378 if (pName) {
a7222a6d 379 /** Matthias 26.04.2007
380 * I spent about a week to investigate a bug which seems to be in ROOT.
381 * Under certain circumstances, TSystem::Unload crashes. The crash occured
382 * for the first time, when libAliHLTUtil was loaded from AliHLTSystem right
383 * after the ComponentHandler was created. It does not occur when dlopen is
384 * used.
385 * It has most likely to do with the garbage collection and automatic
386 * cleanup in ROOT. The crash occurs when ROOT is terminated and before
387 * an instance of AliHLTSystem was created.
388 * root [0] AliHLTSystem gHLT
389 * It does not occur when the instance was created dynamically (but not even
390 * deleted)
391 * root [0] AliHLTSystem* gHLT=new AliHLTSystem
392 *
393 * For that reason, the libraries are not unloaded here, even though there
394 * will be memory leaks.
a742f6f8 395 gSystem->Unload(pName->Data());
a7222a6d 396 */
a742f6f8 397 }
398 else {
399 HLTError("missing library name, can not unload");
c215072c 400 }
a742f6f8 401 delete pCount;
402 }
403#endif //HAVE_DLFCN_H
5df0cbb9 404 handle.fName=NULL;
405 handle.fHandle=NULL;
a742f6f8 406 if (pName) {
407 HLTDebug("unload library %s", pName->Data());
408 delete pName;
409 } else {
410 HLTWarning("missing name for unloaded library");
411 }
412 pName=NULL;
413 return iResult;
414}
415
416int AliHLTComponentHandler::UnloadLibraries()
417{
418 // see header file for class documentation
419 int iResult=0;
420 vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
421 while (element!=fLibraryList.end()) {
422 UnloadLibrary(*element);
c215072c 423 fLibraryList.erase(element);
424 element=fLibraryList.begin();
f23a6e1a 425 }
426 return iResult;
427}
9ce4bf4a 428
85f0cede 429void* AliHLTComponentHandler::FindSymbol(const char* library, const char* symbol)
430{
431 // see header file for class documentation
432 AliHLTLibHandle* hLib=FindLibrary(library);
433 if (hLib==NULL) return NULL;
434 void* pFunc=NULL;
435#ifdef HAVE_DLFCN_H
5df0cbb9 436 pFunc=dlsym(hLib->fHandle, symbol);
85f0cede 437#else
5df0cbb9 438 TString* name=reinterpret_cast<TString*>(hLib->fName);
85f0cede 439 pFunc=gSystem->DynFindSymbol(name->Data(), symbol);
440#endif
441 return pFunc;
442}
443
444AliHLTComponentHandler::AliHLTLibHandle* AliHLTComponentHandler::FindLibrary(const char* library)
445{
446 // see header file for class documentation
447 AliHLTLibHandle* hLib=NULL;
448 vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
449 while (element!=fLibraryList.end()) {
5df0cbb9 450 TString* name=reinterpret_cast<TString*>((*element).fName);
85f0cede 451 if (name->CompareTo(library)==0) {
452 hLib=&(*element);
453 break;
454 }
455 element++;
456 }
457 return hLib;
458}
459
9ce4bf4a 460int AliHLTComponentHandler::AddStandardComponents()
461{
70ed7d01 462 // see header file for class documentation
9ce4bf4a 463 int iResult=0;
464 AliHLTComponent::SetGlobalComponentHandler(this);
242bb794 465// fStandardList.push_back(new AliHLTFilePublisher);
a742f6f8 466// fStandardList.push_back(new AliHLTFileWriter);
242bb794 467// fStandardList.push_back(new AliHLTRootFilePublisherComponent);
468// fStandardList.push_back(new AliHLTRootFileWriterComponent);
9ce4bf4a 469 AliHLTComponent::UnsetGlobalComponentHandler();
470 iResult=RegisterScheduledComponents();
471 return iResult;
472}
473
474int AliHLTComponentHandler::RegisterScheduledComponents()
475{
70ed7d01 476 // see header file for class documentation
9ce4bf4a 477 int iResult=0;
478 vector<AliHLTComponent*>::iterator element=fScheduleList.begin();
479 int iLocalResult=0;
480 while (element!=fScheduleList.end()) {
481 iLocalResult=RegisterComponent(*element);
482 if (iResult==0) iResult=iLocalResult;
483 fScheduleList.erase(element);
484 element=fScheduleList.begin();
485 }
486 return iResult;
487}
488
489int AliHLTComponentHandler::DeleteStandardComponents()
490{
70ed7d01 491 // see header file for class documentation
9ce4bf4a 492 int iResult=0;
493 vector<AliHLTComponent*>::iterator element=fStandardList.begin();
494 while (element!=fStandardList.end()) {
5df0cbb9 495 //DeregisterComponent((*element)->GetComponentID());
9ce4bf4a 496 delete(*element);
497 fStandardList.erase(element);
498 element=fStandardList.begin();
499 }
500 return iResult;
501}