LCOV - code coverage report
Current view: top level - HLT/BASE - AliHLTHOMERLibManager.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 12 125 9.6 %
Date: 2016-06-14 17:26:59 Functions: 6 14 42.9 %

          Line data    Source code
       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             :  *                  for The ALICE HLT Project.                            *
       9             :  *                                                                        *
      10             :  * Permission to use, copy, modify and distribute this software and its   *
      11             :  * documentation strictly for non-commercial purposes is hereby granted   *
      12             :  * without fee, provided that the above copyright notice appears in all   *
      13             :  * copies and that both the copyright notice and this permission notice   *
      14             :  * appear in the supporting documentation. The authors make no claims     *
      15             :  * about the suitability of this software for any purpose. It is          *
      16             :  * provided "as is" without express or implied warranty.                  *
      17             :  **************************************************************************/
      18             : 
      19             : /// @file   AliHLTHOMERLibManager.cxx
      20             : /// @author Matthias Richter
      21             : /// @date   
      22             : /// @brief  dynamic HLT HOMER reader/writer generation and destruction.
      23             : 
      24             : #include <cerrno>
      25             : #include <cassert>
      26             : #include "AliHLTHOMERLibManager.h"
      27             : #include "AliHLTHOMERReader.h"
      28             : #include "AliHLTHOMERWriter.h"
      29             : #include "AliHLTLogging.h"
      30             : #include "TString.h"
      31             : #include "TSystem.h"
      32             : 
      33             : /** ROOT macro for the implementation of ROOT specific class methods */
      34         126 : ClassImp(AliHLTHOMERLibManager)
      35             : 
      36             : // global flag of the library status
      37             : int AliHLTHOMERLibManager::fgLibraryStatus=0;
      38             : // This list must be NULL terminated, since we use it as a marker to identify
      39             : // the end of the list.
      40             : const char* AliHLTHOMERLibManager::fgkLibraries[] = {"libAliHLTHOMER.so", "libHOMER.so", NULL};
      41             : // The size of the list of reference counts must be one less than fgkLibraries.
      42             : int AliHLTHOMERLibManager::fgkLibRefCount[] = {0, 0};
      43             : 
      44             : AliHLTHOMERLibManager::AliHLTHOMERLibManager()
      45             :   :
      46           4 :   fFctCreateReaderFromTCPPort(NULL),
      47           4 :   fFctCreateReaderFromTCPPorts(NULL),
      48           4 :   fFctCreateReaderFromBuffer(NULL),
      49           4 :   fFctDeleteReader(NULL),
      50           4 :   fFctCreateWriter(NULL),
      51           4 :   fFctDeleteWriter(NULL),
      52           4 :   fLoadedLib(NULL)
      53          16 : {
      54             :   // constructor
      55             :   // 
      56             :   // Interface to the HLT Online Monitoring Including Root (HOMER) library.
      57             :   // It allows to decouple the HLT base library from this additional library
      58             :   // while providing the basic functionality to the component libraries
      59           8 : }
      60             : 
      61             : AliHLTHOMERLibManager::~AliHLTHOMERLibManager()
      62          16 : {
      63             :   // destructor
      64             :   //
      65             :   // the library load strategy has been changed in March 2013 in order to
      66             :   // stabilize the runtime memory layout of AliRoot in an attemp to get control
      67             :   // over memory corruptions
      68             :   //  UnloadHOMERLibrary();
      69          16 : }
      70             : 
      71             : AliHLTHOMERReader* AliHLTHOMERLibManager::OpenReader(const char* hostname, unsigned short port )
      72             : {
      73             :   // Open Reader instance for host
      74           0 :   if (fgLibraryStatus<0) return NULL;
      75             : 
      76           0 :   fgLibraryStatus=LoadHOMERLibrary();
      77           0 :   if (fgLibraryStatus <= 0) {
      78           0 :         return NULL;
      79             :   }
      80             :   
      81             :   AliHLTHOMERReader* pReader=NULL;
      82           0 :   if (fFctCreateReaderFromTCPPort!=NULL && (pReader=(((AliHLTHOMERReaderCreateFromTCPPort_t)fFctCreateReaderFromTCPPort)(hostname, port)))==NULL) {
      83           0 :     cout <<"can not create instance of HOMER reader from ports" << endl;
      84           0 :   }
      85             :   
      86             :   return pReader;
      87           0 : }
      88             : 
      89             : AliHLTHOMERReader* AliHLTHOMERLibManager::OpenReader(unsigned int tcpCnt, const char** hostnames, unsigned short* ports)
      90             : {
      91             :   // Open Reader instance for a list of hosts
      92           0 :   if (fgLibraryStatus<0) return NULL;
      93             : 
      94           0 :   fgLibraryStatus=LoadHOMERLibrary();
      95           0 :   if (fgLibraryStatus <= 0) {
      96           0 :         return NULL;
      97             :   }
      98             :   
      99             :   AliHLTHOMERReader* pReader=NULL;
     100           0 :   if (fFctCreateReaderFromTCPPorts!=NULL && (pReader=(((AliHLTHOMERReaderCreateFromTCPPorts_t)fFctCreateReaderFromTCPPorts)(tcpCnt, hostnames, ports)))==NULL) {
     101             :     //HLTError("can not create instance of HOMER reader (function %p)", fFctCreateReaderFromTCPPorts);
     102           0 :     cout << "can not create instance of HOMER reader from port"<<endl;
     103           0 :   }
     104             :   
     105             :   return pReader;
     106           0 : }
     107             : 
     108             : AliHLTHOMERReader* AliHLTHOMERLibManager::OpenReaderBuffer(const AliHLTUInt8_t* pBuffer, int size)
     109             : {
     110             :   // Open Reader instance for a data buffer
     111           0 :   if (fgLibraryStatus<0) return NULL;
     112             : 
     113           0 :   fgLibraryStatus=LoadHOMERLibrary();
     114           0 :   if (fgLibraryStatus <= 0) {
     115           0 :         return NULL;
     116             :   }
     117             :   
     118             :   AliHLTHOMERReader* pReader=NULL;
     119           0 :   if (fFctCreateReaderFromBuffer!=NULL && (pReader=(((AliHLTHOMERReaderCreateFromBuffer_t)fFctCreateReaderFromBuffer)(pBuffer, size)))==NULL) {
     120             :     //HLTError("can not create instance of HOMER reader (function %p)", fFctCreateReaderFromBuffer);
     121             :   }
     122             :   
     123             :   return pReader;
     124           0 : }
     125             : 
     126             : int AliHLTHOMERLibManager::DeleteReader(AliHLTHOMERReader* pReader)
     127             : {
     128             :   // delete a reader
     129             : 
     130             :   // the actual deletion function is inside the HOMER library
     131           0 :   if (fgLibraryStatus<0) return fgLibraryStatus;
     132             : 
     133           0 :   fgLibraryStatus=LoadHOMERLibrary();
     134           0 :   if (fgLibraryStatus <= 0) {
     135           0 :         return fgLibraryStatus;
     136             :   }
     137             :   
     138           0 :   if (fFctDeleteReader!=NULL) {
     139           0 :     ((AliHLTHOMERReaderDelete_t)fFctDeleteReader)(pReader);
     140           0 :   }
     141             :   
     142           0 :   return 0;
     143           0 : }
     144             : 
     145             : AliHLTHOMERWriter* AliHLTHOMERLibManager::OpenWriter()
     146             : {
     147             :   // open a Writer instance
     148           0 :   if (fgLibraryStatus<0) return NULL;
     149             : 
     150           0 :   fgLibraryStatus=LoadHOMERLibrary();
     151           0 :   if (fgLibraryStatus <= 0) {
     152           0 :         return NULL;
     153             :   }
     154             :   
     155             :   AliHLTHOMERWriter* pWriter=NULL;
     156           0 :   if (fFctCreateWriter!=NULL && (pWriter=(((AliHLTHOMERWriterCreate_t)fFctCreateWriter)()))==NULL) {
     157             : //     HLTError("can not create instance of HOMER writer (function %p)", fFctCreateWriter);
     158             :   }
     159             :   
     160             :   return pWriter;
     161           0 : }
     162             : 
     163             : int AliHLTHOMERLibManager::DeleteWriter(AliHLTHOMERWriter* pWriter)
     164             : {
     165             :   // see header file for class documentation
     166           0 :   if (fgLibraryStatus<0) return fgLibraryStatus;
     167             : 
     168           0 :   fgLibraryStatus=LoadHOMERLibrary();
     169           0 :   if (fgLibraryStatus <= 0) {
     170           0 :         return fgLibraryStatus;
     171             :   }
     172             :   
     173           0 :   if (fFctDeleteWriter!=NULL) {
     174           0 :     ((AliHLTHOMERWriterDelete_t)fFctDeleteWriter)(pWriter);
     175           0 :   }
     176             :   
     177           0 :   return 0;
     178           0 : }
     179             : 
     180             : int AliHLTHOMERLibManager::LoadHOMERLibrary()
     181             : {
     182             :   // delete a writer
     183             : 
     184             :   // the actual deletion function is inside the HOMER library
     185             :   int iResult=-EBADF;
     186             :   const char** library=&fgkLibraries[0];
     187             :   int* refcount = &fgkLibRefCount[0];
     188           0 :   do {
     189           0 :     TString libs = gSystem->GetLibraries();
     190           0 :     if (libs.Contains(*library) ||
     191           0 :         (gSystem->Load(*library)) >= 0) {
     192           0 :       ++(*refcount);
     193           0 :       fLoadedLib = *library;
     194             :       iResult=1;
     195           0 :       break;
     196             :     }
     197           0 :     ++library;
     198           0 :     ++refcount;
     199           0 :   } while ((*library)!=NULL);
     200             : 
     201           0 :   if (iResult>0 && *library!=NULL) {
     202             :     // print compile info
     203             :     typedef void (*CompileInfo)( char*& date, char*& time);
     204             : 
     205           0 :     fFctCreateReaderFromTCPPort=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERREADER_CREATE_FROM_TCPPORT);
     206           0 :     fFctCreateReaderFromTCPPorts=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERREADER_CREATE_FROM_TCPPORTS);
     207           0 :     fFctCreateReaderFromBuffer=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERREADER_CREATE_FROM_BUFFER);
     208           0 :     fFctDeleteReader=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERREADER_DELETE);
     209           0 :     fFctCreateWriter=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERWRITER_CREATE);
     210           0 :     fFctDeleteWriter=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERWRITER_DELETE);
     211           0 :     if (fFctCreateReaderFromTCPPort==NULL ||
     212           0 :         fFctCreateReaderFromTCPPorts==NULL ||
     213           0 :         fFctCreateReaderFromBuffer==NULL || 
     214           0 :         fFctDeleteReader==NULL ||
     215           0 :         fFctCreateWriter==NULL ||
     216           0 :         fFctDeleteWriter==NULL) {
     217             :       iResult=-ENOSYS;
     218           0 :     } else {
     219             :     }
     220             :   }
     221           0 :   if (iResult<0 || *library==NULL) {
     222           0 :     fFctCreateReaderFromTCPPort=NULL;
     223           0 :     fFctCreateReaderFromTCPPorts=NULL;
     224           0 :     fFctCreateReaderFromBuffer=NULL;
     225           0 :     fFctDeleteReader=NULL;
     226           0 :     fFctCreateWriter=NULL;
     227           0 :     fFctDeleteWriter=NULL;
     228           0 :   }
     229             : 
     230           0 :   return iResult;
     231           0 : }
     232             : 
     233             : int AliHLTHOMERLibManager::UnloadHOMERLibrary()
     234             : {
     235             :   // unload HOMER library
     236             :   int iResult=0;
     237             :   
     238           0 :   if (fLoadedLib != NULL)
     239             :   {
     240             :     // Find the corresponding reference count.
     241             :     const char** library=&fgkLibraries[0];
     242             :     int* refcount = &fgkLibRefCount[0];
     243           0 :     while (*library != NULL)
     244             :     {
     245           0 :       if (strcmp(*library, fLoadedLib) == 0) break;
     246           0 :       ++library;
     247           0 :       ++refcount;
     248             :     }
     249             :     
     250             :     // Decrease the reference count and remove the library if it is zero.
     251           0 :     if (*refcount >= 0) --(*refcount);
     252           0 :     if (*refcount == 0)
     253             :     {
     254             :       // Check that the library we are trying to unload is actually the last library
     255             :       // in the gSystem->GetLibraries() list. If not then we must abort the removal.
     256             :       // This is because of a ROOT bug/feature/limitation. If we try unload the library
     257             :       // then ROOT will also wipe all libraries in the gSystem->GetLibraries() list
     258             :       // following the library we want to unload.
     259           0 :       TString libstring = gSystem->GetLibraries();
     260           0 :       TString token, lastlib;
     261           0 :       Ssiz_t from = 0;
     262             :       Int_t numOfLibs = 0, posOfLib = -1;
     263           0 :       while (libstring.Tokenize(token, from, " "))
     264             :       {
     265           0 :         ++numOfLibs;
     266           0 :         lastlib = token;
     267           0 :         if (token.Contains(fLoadedLib)) posOfLib = numOfLibs;
     268             :       }
     269           0 :       if (numOfLibs == posOfLib)
     270             :       {
     271           0 :         gSystem->Unload(fLoadedLib);
     272             : 
     273             :         // Check that the library is gone, since Unload() does not return a status code.
     274           0 :         libstring = gSystem->GetLibraries();
     275           0 :         if (libstring.Contains(fLoadedLib)) iResult = -EBADF;
     276             :       }
     277             :       else
     278             :       {
     279           0 :         AliHLTLogging log;
     280           0 :         log.LoggingVarargs(kHLTLogWarning, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
     281           0 :           Form("ROOT limitation! Cannot properly cleanup and unload the shared"
     282             :             " library '%s' since another library '%s' was loaded afterwards. Trying to"
     283             :             " unload this library will remove the others and lead to serious memory faults.",
     284           0 :             fLoadedLib, lastlib.Data()
     285             :         ));
     286           0 :       }
     287           0 :     }
     288           0 :   }
     289             : 
     290             :   // Clear the function pointers.
     291           0 :   fFctCreateReaderFromTCPPort = NULL;
     292           0 :   fFctCreateReaderFromTCPPorts = NULL;
     293           0 :   fFctCreateReaderFromBuffer = NULL;
     294           0 :   fFctDeleteReader = NULL;
     295           0 :   fFctCreateWriter = NULL;
     296           0 :   fFctDeleteWriter = NULL;
     297             : 
     298           0 :   return iResult;
     299           0 : }

Generated by: LCOV version 1.11