]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTComponentHandler.cxx
corrected compilation warnings
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTComponentHandler.cxx
1 // $Id$
2
3 /**************************************************************************
4  * This file is property of and copyright by the ALICE HLT Project        * 
5  * ALICE Experiment at CERN, All rights reserved.                         *
6  *                                                                        *
7  * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
8  *                  Timm Steinbeck <timm@kip.uni-heidelberg.de>           *
9  *                  for The ALICE HLT Project.                            *
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
20 /** @file   AliHLTComponentHandler.cxx
21     @author Matthias Richter, Timm Steinbeck
22     @date   
23     @brief  Implementation of HLT component handler. */
24
25 #if __GNUC__>= 3
26 using namespace std;
27 #endif
28 //#undef HAVE_DLFCN_H
29 #ifdef HAVE_DLFCN_H
30 #include <dlfcn.h>
31 #else
32 //#include <Riostream.h>
33 #include <TSystem.h>
34 #endif //HAVE_DLFCN_H
35 //#include "AliHLTStdIncludes.h"
36 #include "AliHLTComponentHandler.h"
37 #include "AliHLTComponent.h"
38 #include "AliHLTDataTypes.h"
39 //#include "AliHLTSystem.h"
40 #include "TString.h"
41
42 // the standard components
43 // #include "AliHLTFilePublisher.h"
44 // #include "AliHLTFileWriter.h"
45 // #include "AliHLTRootFilePublisherComponent.h"
46 // #include "AliHLTRootFileWriterComponent.h"
47
48 /** ROOT macro for the implementation of ROOT specific class methods */
49 ClassImp(AliHLTComponentHandler)
50
51 AliHLTComponentHandler::AliHLTComponentHandler()
52   :
53   fComponentList(),
54   fScheduleList(),
55   fLibraryList(),
56   fEnvironment(),
57   fStandardList()
58 {
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
64   memset(&fEnvironment, 0, sizeof(AliHLTComponentEnvironment));
65   AddStandardComponents();
66 }
67
68 AliHLTComponentHandler::AliHLTComponentHandler(AliHLTComponentEnvironment* pEnv)
69   :
70   AliHLTLogging(),
71   fComponentList(),
72   fScheduleList(),
73   fLibraryList(),
74   fEnvironment(),
75   fStandardList()
76 {
77   // see header file for class documentation
78   if (pEnv) {
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
84       // for redirection
85       AliHLTLogging::Init(pEnv->fLoggingFunc);
86     }
87   }  else
88     memset(&fEnvironment, 0, sizeof(AliHLTComponentEnvironment));
89   AddStandardComponents();
90 }
91
92 AliHLTComponentHandler::~AliHLTComponentHandler()
93 {
94   // see header file for class documentation
95   DeleteStandardComponents();
96   UnloadLibraries();
97 }
98
99 int AliHLTComponentHandler::AnnounceVersion()
100 {
101   // see header file for class documentation
102   int iResult=0;
103 #ifdef PACKAGE_STRING
104   void HLTbaseCompileInfo( char*& date, char*& time);
105   char* date="";
106   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);
111 #else
112   HLTInfo("ALICE High Level Trigger build on %s (%s) (embedded AliRoot build)", __DATE__, __TIME__);
113 #endif
114   return iResult;
115 }
116
117 Int_t AliHLTComponentHandler::RegisterComponent(AliHLTComponent* pSample)
118 {
119   // see header file for class documentation
120   Int_t iResult=0;
121   if (pSample) {
122     if (FindComponent(pSample->GetComponentID())==NULL) {
123       iResult=InsertComponent(pSample);
124       if (iResult>=0) {
125         HLTInfo("component %s registered", pSample->GetComponentID());
126       }
127     } else {
128       // component already registered
129       HLTDebug("component %s already registered, skipped", pSample->GetComponentID());
130       iResult=-EEXIST;
131     }
132   } else {
133     iResult=-EINVAL;
134   }
135   return iResult;
136 }
137
138 int AliHLTComponentHandler::DeregisterComponent( const char* componentID )
139 {
140   // see header file for class documentation
141
142   int iResult=0;
143   if (componentID) {
144     HLTWarning("not yet implemented, please notify the developers if you need this function");
145   } else {
146     iResult=-EINVAL;
147   }
148   return iResult;
149 }
150
151 Int_t AliHLTComponentHandler::ScheduleRegister(AliHLTComponent* pSample)
152 {
153   // see header file for class documentation
154   Int_t iResult=0;
155   if (pSample) {
156     fScheduleList.push_back(pSample);
157   } else {
158     iResult=-EINVAL;
159   }
160   return iResult;
161 }
162
163 int AliHLTComponentHandler::CreateComponent(const char* componentID, void* pEnvParam, int argc, const char** argv, AliHLTComponent*& component )
164 {
165   // see header file for class documentation
166   int iResult=0;
167   if (componentID) {
168     AliHLTComponent* pSample=FindComponent(componentID);
169     if (pSample!=NULL) {
170       component=pSample->Spawn();
171       if (component) {
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);
175           delete component;
176           component=NULL;
177         }
178       } else {
179         HLTError("can not spawn component \"%s\"", componentID);
180         iResult=-ENOENT;
181       }
182     } else {
183       HLTWarning("can not find component \"%s\"", componentID);
184       iResult=-ENOENT;
185     }
186   } else {
187     iResult=-EINVAL;
188   }
189   return iResult;
190 }
191
192 Int_t AliHLTComponentHandler::FindComponentIndex(const char* componentID)
193 {
194   // see header file for class documentation
195   Int_t iResult=0;
196   if (componentID) {
197     vector<AliHLTComponent*>::iterator element=fComponentList.begin();
198     while (element!=fComponentList.end() && iResult>=0) {
199       if (strcmp(componentID, (*element)->GetComponentID())==0) {
200         break;
201       }
202       element++;
203       iResult++;
204     }
205     if (element==fComponentList.end()) iResult=-ENOENT;
206   } else {
207     iResult=-EINVAL;
208   }
209   return iResult;
210 }
211
212 AliHLTComponent* AliHLTComponentHandler::FindComponent(const char* componentID)
213 {
214   // see header file for class documentation
215   AliHLTComponent* pSample=NULL;
216   Int_t index=FindComponentIndex(componentID);
217   if (index>=0) {
218     pSample=(AliHLTComponent*)fComponentList.at(index);
219   }
220   return pSample;
221 }
222
223 Int_t AliHLTComponentHandler::InsertComponent(AliHLTComponent* pSample)
224 {
225   // see header file for class documentation
226   Int_t iResult=0;
227   if (pSample!=NULL) {
228     fComponentList.push_back(pSample);
229   } else {
230     iResult=-EINVAL;
231   }
232   return iResult;
233 }
234
235 void AliHLTComponentHandler::List() 
236 {
237   // see header file for class documentation
238   vector<AliHLTComponent*>::iterator element=fComponentList.begin();
239   int index=0;
240   while (element!=fComponentList.end()) {
241     HLTInfo("%d. %s", index++, (*element++)->GetComponentID());
242   }
243 }
244
245 void AliHLTComponentHandler::SetEnvironment(AliHLTComponentEnvironment* pEnv) 
246 {
247   // see header file for class documentation
248   if (pEnv) {
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
254       // for redirection
255       AliHLTLogging::Init(fEnvironment.fLoggingFunc);
256     }
257   }
258 }
259
260 int AliHLTComponentHandler::LoadLibrary( const char* libraryPath )
261 {
262   // see header file for class documentation
263   int iResult=0;
264   if (libraryPath) {
265     AliHLTComponent::SetGlobalComponentHandler(this);
266     AliHLTLibHandle hLib;
267     const char* loadtype="";
268 #ifdef HAVE_DLFCN_H
269     // use interface to the dynamic linking loader
270     hLib.fHandle=dlopen(libraryPath, RTLD_NOW);
271     loadtype="dlopen";
272 #else
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);
277     if (pLib) {
278         int* pRootHandle=reinterpret_cast<int*>(pLib->fHandle);
279         (*pRootHandle)++;
280         HLTDebug("instance %d of library %s loaded", (*pRootHandle), libraryPath);
281         hLib.fHandle=pRootHandle;
282     }
283     
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);
289     }
290     loadtype="gSystem";
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");
299       if (fctInfo) {
300         char* date="";
301         char* time="";
302         (*fctInfo)(date, time);
303         if (!date) date="unknown";
304         if (!time) time="unknown";
305         HLTInfo("build on %s (%s)", date, time);
306       } else {
307         HLTInfo("no build info available (possible AliRoot embedded build)");
308       }
309       iResult=RegisterScheduledComponents();
310     } else {
311       HLTError("can not load library %s", libraryPath);
312 #ifdef HAVE_DLFCN_H
313       HLTError("dlopen error: %s", dlerror());
314 #endif //HAVE_DLFCN_H
315 #ifdef __APPLE__
316       iResult=-EFTYPE;
317 #else
318       iResult=-ELIBACC;
319 #endif
320     }
321     AliHLTComponent::UnsetGlobalComponentHandler();
322   } else {
323     iResult=-EINVAL;
324   }
325   return iResult;
326 }
327
328 int AliHLTComponentHandler::UnloadLibrary( const char* libraryPath )
329 {
330   // see header file for class documentation
331   int iResult=0;
332   if (libraryPath) {
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);
339         break;
340       }
341       element++;
342   }
343   } else {
344     iResult=-EINVAL;
345   }
346   return iResult;
347 }
348
349 int AliHLTComponentHandler::UnloadLibrary(AliHLTComponentHandler::AliHLTLibHandle &handle)
350 {
351   // see header file for class documentation
352   int iResult=0;
353   fgAliLoggingFunc=NULL;
354   TString* pName=reinterpret_cast<TString*>(handle.fName);
355 #ifdef HAVE_DLFCN_H
356   dlclose(handle.fHandle);
357 #else
358   int* pCount=reinterpret_cast<int*>(handle.fHandle);
359   if (--(*pCount)==0) {
360     if (pName) {
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
366        * used. 
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
372        * deleted)
373        *   root [0] AliHLTSystem* gHLT=new AliHLTSystem
374        *
375        * For that reason, the libraries are not unloaded here, even though there
376        * will be memory leaks.
377       gSystem->Unload(pName->Data());
378        */
379     }
380     else {
381       HLTError("missing library name, can not unload");
382     }
383     delete pCount;
384   }
385 #endif //HAVE_DLFCN_H
386   handle.fName=NULL;
387   handle.fHandle=NULL;
388   if (pName) {
389     HLTDebug("unload library %s", pName->Data());
390     delete pName;
391   } else {
392     HLTWarning("missing name for unloaded library");
393   }
394   pName=NULL;
395   return iResult;
396 }
397
398 int AliHLTComponentHandler::UnloadLibraries()
399 {
400   // see header file for class documentation
401   int iResult=0;
402   vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
403   while (element!=fLibraryList.end()) {
404     UnloadLibrary(*element);
405     fLibraryList.erase(element);
406     element=fLibraryList.begin();
407   }
408   return iResult;
409 }
410
411 void* AliHLTComponentHandler::FindSymbol(const char* library, const char* symbol)
412 {
413   // see header file for class documentation
414   AliHLTLibHandle* hLib=FindLibrary(library);
415   if (hLib==NULL) return NULL;
416   void* pFunc=NULL;
417 #ifdef HAVE_DLFCN_H
418   pFunc=dlsym(hLib->fHandle, symbol);
419 #else
420   TString* name=reinterpret_cast<TString*>(hLib->fName);
421   pFunc=gSystem->DynFindSymbol(name->Data(), symbol);
422 #endif
423   return pFunc;
424 }
425
426 AliHLTComponentHandler::AliHLTLibHandle* AliHLTComponentHandler::FindLibrary(const char* library)
427 {
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) {
434       hLib=&(*element);
435       break;
436     }
437     element++;
438   }
439   return hLib;
440 }
441
442 int AliHLTComponentHandler::AddStandardComponents()
443 {
444   // see header file for class documentation
445   int iResult=0;
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();
453   return iResult;
454 }
455
456 int AliHLTComponentHandler::RegisterScheduledComponents()
457 {
458   // see header file for class documentation
459   int iResult=0;
460   vector<AliHLTComponent*>::iterator element=fScheduleList.begin();
461   int iLocalResult=0;
462   while (element!=fScheduleList.end()) {
463     iLocalResult=RegisterComponent(*element);
464     if (iResult==0) iResult=iLocalResult;
465     fScheduleList.erase(element);
466     element=fScheduleList.begin();
467   }
468   return iResult;
469 }
470
471 int AliHLTComponentHandler::DeleteStandardComponents()
472 {
473   // see header file for class documentation
474   int iResult=0;
475   vector<AliHLTComponent*>::iterator element=fStandardList.begin();
476   while (element!=fStandardList.end()) {
477     //DeregisterComponent((*element)->GetComponentID());
478     delete(*element);
479     fStandardList.erase(element);
480     element=fStandardList.begin();
481   }
482   return iResult;
483 }