]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - HLT/BASE/AliHLTComponentHandler.cxx
Air with increased transport cuts close to qb28.
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTComponentHandler.cxx
index 48350854c06cddbe1f11589762b692625ffa7411..28a829399f0169f756cf6479ed113d722ee588dd 100644 (file)
@@ -38,9 +38,10 @@ using namespace std;
 #include "AliHLTSystem.h"
 
 // the standard components
-#include "AliHLTFilePublisher.h"
-#include "AliHLTFileWriter.h"
-#include "AliHLTRootFileWriterComponent.h"
+// #include "AliHLTFilePublisher.h"
+// #include "AliHLTFileWriter.h"
+// #include "AliHLTRootFilePublisherComponent.h"
+// #include "AliHLTRootFileWriterComponent.h"
 
 /** ROOT macro for the implementation of ROOT specific class methods */
 ClassImp(AliHLTComponentHandler)
@@ -73,7 +74,13 @@ AliHLTComponentHandler::AliHLTComponentHandler(AliHLTComponentEnvironment* pEnv)
   // see header file for class documentation
   if (pEnv) {
     memcpy(&fEnvironment, pEnv, sizeof(AliHLTComponentEnvironment));
-    AliHLTLogging::Init(pEnv->fLoggingFunc);
+    if (pEnv->fLoggingFunc) {
+      // the AliHLTLogging::Init method also sets the stream output
+      // and notification handler to AliLog. This should only be done
+      // if the logging environment contains a logging function
+      // for redirection
+      AliHLTLogging::Init(pEnv->fLoggingFunc);
+    }
   }  else
     memset(&fEnvironment, 0, sizeof(AliHLTComponentEnvironment));
   AddStandardComponents();
@@ -82,8 +89,8 @@ AliHLTComponentHandler::AliHLTComponentHandler(AliHLTComponentEnvironment* pEnv)
 AliHLTComponentHandler::~AliHLTComponentHandler()
 {
   // see header file for class documentation
-  UnloadLibraries();
   DeleteStandardComponents();
+  UnloadLibraries();
 }
 
 int AliHLTComponentHandler::AnnounceVersion()
@@ -99,7 +106,7 @@ int AliHLTComponentHandler::AnnounceVersion()
   if (!time) time="unknown";
   HLTInfo("%s build on %s (%s)", PACKAGE_STRING, date, time);
 #else
-  HLTInfo("ALICE High Level Trigger (embedded AliRoot build)");
+  HLTInfo("ALICE High Level Trigger build on %s (%s) (embedded AliRoot build)", __DATE__, __TIME__);
 #endif
   return iResult;
 }
@@ -235,7 +242,13 @@ void AliHLTComponentHandler::SetEnvironment(AliHLTComponentEnvironment* pEnv)
   // see header file for class documentation
   if (pEnv) {
     memcpy(&fEnvironment, pEnv, sizeof(AliHLTComponentEnvironment));
-    AliHLTLogging::Init(fEnvironment.fLoggingFunc);
+    if (fEnvironment.fLoggingFunc) {
+      // the AliHLTLogging::Init method also sets the stream output
+      // and notification handler to AliLog. This should only be done
+      // if the logging environment contains a logging function
+      // for redirection
+      AliHLTLogging::Init(fEnvironment.fLoggingFunc);
+    }
   }
 }
 
@@ -245,20 +258,37 @@ int AliHLTComponentHandler::LoadLibrary( const char* libraryPath )
   int iResult=0;
   if (libraryPath) {
     AliHLTComponent::SetGlobalComponentHandler(this);
-    AliHLTLibHandle hLib=NULL;
+    AliHLTLibHandle hLib;
+    const char* loadtype="";
 #ifdef HAVE_DLFCN_H
     // use interface to the dynamic linking loader
-    hLib=dlopen(libraryPath, RTLD_NOW);
+    hLib.handle=dlopen(libraryPath, RTLD_NOW);
+    loadtype="dlopen";
 #else
     // use ROOT dynamic loader
-    if (gSystem->Load(libraryPath)==0) {
-      // create TString object to store library path and use pointer as handle 
-      hLib=reinterpret_cast<AliHLTLibHandle>(new TString(libraryPath));
+    // check if the library was already loaded, as Load returns
+    // 'failure' if the library was already loaded
+    AliHLTLibHandle* pLib=FindLibrary(libraryPath);
+    if (pLib) {
+       int* pRootHandle=reinterpret_cast<int*>(pLib->handle);
+       (*pRootHandle)++;
+       HLTDebug("instance %d of library %s loaded", (*pRootHandle), libraryPath);
+       hLib.handle=pRootHandle;
+    }
+    
+    if (hLib.handle==NULL && gSystem->Load(libraryPath)==0) {
+      int* pRootHandle=new int;
+      if (pRootHandle) *pRootHandle=1;
+      hLib.handle=pRootHandle;
+      //HLTDebug("library %s loaded via gSystem", libraryPath);
     }
+    loadtype="gSystem";
 #endif //HAVE_DLFCN_H
-    if (hLib) {
-      HLTInfo("library %s loaded", libraryPath);
-      fLibraryList.push_back(hLib);
+    if (hLib.handle!=NULL) {
+      // create TString object to store library path and use pointer as handle 
+      hLib.name=new TString(libraryPath);
+      HLTInfo("library %s loaded (%s)", libraryPath, loadtype);
+      fLibraryList.insert(fLibraryList.begin(), hLib);
       iResult=RegisterScheduledComponents();
     } else {
       HLTError("can not load library %s", libraryPath);
@@ -283,28 +313,113 @@ int AliHLTComponentHandler::UnloadLibrary( const char* libraryPath )
   // see header file for class documentation
   int iResult=0;
   if (libraryPath) {
+    vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
+    while (element!=fLibraryList.end()) {
+      TString* pName=reinterpret_cast<TString*>((*element).name);
+      if (pName->CompareTo(libraryPath)==0) {
+       UnloadLibrary(*element);
+       fLibraryList.erase(element);
+       break;
+      }
+      element++;
+  }
   } else {
     iResult=-EINVAL;
   }
   return iResult;
 }
 
+int AliHLTComponentHandler::UnloadLibrary(AliHLTComponentHandler::AliHLTLibHandle &handle)
+{
+  // see header file for class documentation
+  int iResult=0;
+  fgAliLoggingFunc=NULL;
+  TString* pName=reinterpret_cast<TString*>(handle.name);
+#ifdef HAVE_DLFCN_H
+  dlclose(handle.handle);
+#else
+  int* pCount=reinterpret_cast<int*>(handle.handle);
+  if (--(*pCount)==0) {
+    if (pName) {
+      /** Matthias 26.04.2007
+       * I spent about a week to investigate a bug which seems to be in ROOT.
+       * Under certain circumstances, TSystem::Unload crashes. The crash occured
+       * for the first time, when libAliHLTUtil was loaded from AliHLTSystem right
+       * after the ComponentHandler was created. It does not occur when dlopen is
+       * used. 
+       * It has most likely to do with the garbage collection and automatic
+       * cleanup in ROOT. The crash occurs when ROOT is terminated and before
+       * an instance of AliHLTSystem was created.
+       *   root [0] AliHLTSystem gHLT
+       * It does not occur when the instance was created dynamically (but not even
+       * deleted)
+       *   root [0] AliHLTSystem* gHLT=new AliHLTSystem
+       *
+       * For that reason, the libraries are not unloaded here, even though there
+       * will be memory leaks.
+      gSystem->Unload(pName->Data());
+       */
+    }
+    else {
+      HLTError("missing library name, can not unload");
+    }
+    delete pCount;
+  }
+#endif //HAVE_DLFCN_H
+  handle.name=NULL;
+  handle.handle=NULL;
+  if (pName) {
+    HLTDebug("unload library %s", pName->Data());
+    delete pName;
+  } else {
+    HLTWarning("missing name for unloaded library");
+  }
+  pName=NULL;
+  return iResult;
+}
+
 int AliHLTComponentHandler::UnloadLibraries()
 {
   // see header file for class documentation
   int iResult=0;
   vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
   while (element!=fLibraryList.end()) {
+    UnloadLibrary(*element);
+    fLibraryList.erase(element);
+    element=fLibraryList.begin();
+  }
+  return iResult;
+}
+
+void* AliHLTComponentHandler::FindSymbol(const char* library, const char* symbol)
+{
+  // see header file for class documentation
+  AliHLTLibHandle* hLib=FindLibrary(library);
+  if (hLib==NULL) return NULL;
+  void* pFunc=NULL;
 #ifdef HAVE_DLFCN_H
-    dlclose(*element);
+  pFunc=dlsym(hLib->handle, symbol);
 #else
-    TString* libraryPath=reinterpret_cast<TString*>(*element);
-    gSystem->Unload(libraryPath->Data());
-    delete libraryPath;
-#endif //HAVE_DLFCN_H
+  TString* name=reinterpret_cast<TString*>(hLib->name);
+  pFunc=gSystem->DynFindSymbol(name->Data(), symbol);
+#endif
+  return pFunc;
+}
+
+AliHLTComponentHandler::AliHLTLibHandle* AliHLTComponentHandler::FindLibrary(const char* library)
+{
+  // see header file for class documentation
+  AliHLTLibHandle* hLib=NULL;
+  vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
+  while (element!=fLibraryList.end()) {
+    TString* name=reinterpret_cast<TString*>((*element).name);
+    if (name->CompareTo(library)==0) {
+      hLib=&(*element);
+      break;
+    }
     element++;
   }
-  return iResult;
+  return hLib;
 }
 
 int AliHLTComponentHandler::AddStandardComponents()
@@ -312,9 +427,10 @@ int AliHLTComponentHandler::AddStandardComponents()
   // see header file for class documentation
   int iResult=0;
   AliHLTComponent::SetGlobalComponentHandler(this);
-  fStandardList.push_back(new AliHLTFilePublisher);
-  fStandardList.push_back(new AliHLTFileWriter);
-  fStandardList.push_back(new AliHLTRootFileWriterComponent);
+//   fStandardList.push_back(new AliHLTFilePublisher);
+//   fStandardList.push_back(new AliHLTFileWriter);
+//   fStandardList.push_back(new AliHLTRootFilePublisherComponent);
+//   fStandardList.push_back(new AliHLTRootFileWriterComponent);
   AliHLTComponent::UnsetGlobalComponentHandler();
   iResult=RegisterScheduledComponents();
   return iResult;