]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTHOMERLibManager.cxx
44ddbcce0564f442c8b094a09d24902d5872a7b7
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTHOMERLibManager.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  *                  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 // see header file for class documentation
25 // or
26 // refer to README to build package
27 // or
28 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
29
30 #include <cerrno>
31 #include <cassert>
32 #include "AliHLTHOMERLibManager.h"
33 #include "AliHLTHOMERReader.h"
34 #include "AliHLTHOMERWriter.h"
35 #include "AliHLTLogging.h"
36 #include "TString.h"
37 #include "TSystem.h"
38
39 /** ROOT macro for the implementation of ROOT specific class methods */
40 ClassImp(AliHLTHOMERLibManager)
41
42 // This list must be NULL terminated, since we use it as a marker to identify
43 // the end of the list.
44 const char* AliHLTHOMERLibManager::fgkLibraries[] = {"libAliHLTHOMER.so", "libHOMER.so", NULL};
45 // The size of the list of reference counts must be one less than fgkLibraries.
46 int AliHLTHOMERLibManager::fgkLibRefCount[] = {0, 0};
47
48 AliHLTHOMERLibManager::AliHLTHOMERLibManager()
49   :
50   fLibraryStatus(0),
51   fFctCreateReaderFromTCPPort(NULL),
52   fFctCreateReaderFromTCPPorts(NULL),
53   fFctCreateReaderFromBuffer(NULL),
54   fFctDeleteReader(NULL),
55   fFctCreateWriter(NULL),
56   fFctDeleteWriter(NULL),
57   fLoadedLib(NULL)
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 }
65
66 AliHLTHOMERLibManager::~AliHLTHOMERLibManager()
67 {
68   // see header file for class documentation
69   UnloadHOMERLibrary();
70 }
71
72 AliHLTHOMERReader* AliHLTHOMERLibManager::OpenReader(const char* hostname, unsigned short port )
73 {
74   // see header file for class documentation
75   if (fLibraryStatus<0) return NULL;
76
77   if (fLibraryStatus==0) {
78     fLibraryStatus=LoadHOMERLibrary();
79   }
80   
81   AliHLTHOMERReader* pReader=NULL;
82   if (fFctCreateReaderFromTCPPort!=NULL && (pReader=(((AliHLTHOMERReaderCreateFromTCPPort_t)fFctCreateReaderFromTCPPort)(hostname, port)))==NULL) {
83     cout <<"can not create instance of HOMER reader from ports" << endl;
84   }
85   
86   return pReader;
87 }
88
89 AliHLTHOMERReader* AliHLTHOMERLibManager::OpenReader(unsigned int tcpCnt, const char** hostnames, unsigned short* ports)
90 {
91   // see header file for class documentation
92   if (fLibraryStatus<0) return NULL;
93
94   if (fLibraryStatus==0) {
95     fLibraryStatus=LoadHOMERLibrary();
96   }
97   
98   AliHLTHOMERReader* pReader=NULL;
99   if (fFctCreateReaderFromTCPPorts!=NULL && (pReader=(((AliHLTHOMERReaderCreateFromTCPPorts_t)fFctCreateReaderFromTCPPorts)(tcpCnt, hostnames, ports)))==NULL) {
100     //HLTError("can not create instance of HOMER reader (function %p)", fFctCreateReaderFromTCPPorts);
101     cout << "can not create instance of HOMER reader from port"<<endl;
102   }
103   
104   return pReader;
105 }
106
107 AliHLTHOMERReader* AliHLTHOMERLibManager::OpenReaderBuffer(const AliHLTUInt8_t* pBuffer, int size)
108 {
109   // see header file for class documentation
110   if (fLibraryStatus<0) return NULL;
111
112   if (fLibraryStatus==0) {
113     fLibraryStatus=LoadHOMERLibrary();
114   }
115   
116   AliHLTHOMERReader* pReader=NULL;
117   if (fFctCreateReaderFromBuffer!=NULL && (pReader=(((AliHLTHOMERReaderCreateFromBuffer_t)fFctCreateReaderFromBuffer)(pBuffer, size)))==NULL) {
118     //HLTError("can not create instance of HOMER reader (function %p)", fFctCreateReaderFromBuffer);
119   }
120   
121   return pReader;
122 }
123
124 int AliHLTHOMERLibManager::DeleteReader(AliHLTHOMERReader* pReader)
125 {
126   // see header file for class documentation
127   if (fLibraryStatus<0) return fLibraryStatus;
128
129   if (fLibraryStatus==0) {
130     fLibraryStatus=LoadHOMERLibrary();
131   }
132   
133   if (fFctDeleteReader!=NULL) {
134     ((AliHLTHOMERReaderDelete_t)fFctDeleteReader)(pReader);
135   }
136   
137   return 0;
138 }
139
140 AliHLTHOMERWriter* AliHLTHOMERLibManager::OpenWriter()
141 {
142   // see header file for class documentation
143   if (fLibraryStatus<0) return NULL;
144
145   if (fLibraryStatus==0) {
146     fLibraryStatus=LoadHOMERLibrary();
147   }
148   
149   AliHLTHOMERWriter* pWriter=NULL;
150   if (fFctCreateWriter!=NULL && (pWriter=(((AliHLTHOMERWriterCreate_t)fFctCreateWriter)()))==NULL) {
151 //     HLTError("can not create instance of HOMER writer (function %p)", fFctCreateWriter);
152   }
153   
154   return pWriter;
155 }
156
157 int AliHLTHOMERLibManager::DeleteWriter(AliHLTHOMERWriter* pWriter)
158 {
159   // see header file for class documentation
160   if (fLibraryStatus<0) return fLibraryStatus;
161
162   if (fLibraryStatus==0) {
163     fLibraryStatus=LoadHOMERLibrary();
164   }
165   
166   if (fFctDeleteWriter!=NULL) {
167     ((AliHLTHOMERWriterDelete_t)fFctDeleteWriter)(pWriter);
168   }
169   
170   return 0;
171 }
172
173 int AliHLTHOMERLibManager::LoadHOMERLibrary()
174 {
175   // see header file for class documentation
176   int iResult=-EBADF;
177   const char** library=&fgkLibraries[0];
178   int* refcount = &fgkLibRefCount[0];
179   do {
180     TString libs = gSystem->GetLibraries();
181     if (libs.Contains(*library)) {
182       iResult=1;
183       break;
184     }
185     if ((gSystem->Load(*library)) >= 0) {
186       ++(*refcount);
187       fLoadedLib = *library;
188       iResult=1;
189       break;
190     }
191     ++library;
192     ++refcount;
193   } while ((*library)!=NULL);
194
195   if (iResult>0 && *library!=NULL) {
196     // print compile info
197     typedef void (*CompileInfo)( char*& date, char*& time);
198     CompileInfo fctInfo=(CompileInfo)gSystem->DynFindSymbol(*library, "CompileInfo");
199     if (fctInfo) {
200       char* date=0;
201       char* time=0;
202       (*fctInfo)(date, time);
203       if (!date) {date=new Char_t[8]; strcpy(date,"unknown");}
204       if (!time) {time=new Char_t[8]; strcpy(time,"unknown");}
205       //HLTInfo("%s build on %s (%s)", *library, date, time);
206     } else {
207       //HLTInfo("no build info available for %s", *library);
208     }
209
210     fFctCreateReaderFromTCPPort=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERREADER_CREATE_FROM_TCPPORT);
211     fFctCreateReaderFromTCPPorts=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERREADER_CREATE_FROM_TCPPORTS);
212     fFctCreateReaderFromBuffer=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERREADER_CREATE_FROM_BUFFER);
213     fFctDeleteReader=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERREADER_DELETE);
214     fFctCreateWriter=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERWRITER_CREATE);
215     fFctDeleteWriter=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERWRITER_DELETE);
216     if (fFctCreateReaderFromTCPPort==NULL ||
217         fFctCreateReaderFromTCPPorts==NULL ||
218         fFctCreateReaderFromBuffer==NULL || 
219         fFctDeleteReader==NULL ||
220         fFctCreateWriter==NULL ||
221         fFctDeleteWriter==NULL) {
222       iResult=-ENOSYS;
223     } else {
224     }
225   }
226   if (iResult<0 || *library==NULL) {
227     fFctCreateReaderFromTCPPort=NULL;
228     fFctCreateReaderFromTCPPorts=NULL;
229     fFctCreateReaderFromBuffer=NULL;
230     fFctDeleteReader=NULL;
231     fFctCreateWriter=NULL;
232     fFctDeleteWriter=NULL;
233   }
234
235   return iResult;
236 }
237
238 int AliHLTHOMERLibManager::UnloadHOMERLibrary()
239 {
240   // see header file for class documentation
241   int iResult=0;
242   
243   if (fLoadedLib != NULL)
244   {
245     // Find the corresponding reference count.
246     const char** library=&fgkLibraries[0];
247     int* refcount = &fgkLibRefCount[0];
248     while (*library != NULL)
249     {
250       if (strcmp(*library, fLoadedLib) == 0) break;
251       ++library;
252       ++refcount;
253     }
254     
255     // Decrease the reference count and remove the library if it is zero.
256     if (*refcount >= 0) --(*refcount);
257     if (*refcount == 0)
258     {
259       // Check that the library we are trying to unload is actually the last library
260       // in the gSystem->GetLibraries() list. If not then we must abort the removal.
261       // This is because of a ROOT bug/feature/limitation. If we try unload the library
262       // then ROOT will also wipe all libraries in the gSystem->GetLibraries() list
263       // following the library we want to unload.
264       TString libstring = gSystem->GetLibraries();
265       TString token, lastlib;
266       Ssiz_t from = 0;
267       Int_t numOfLibs = 0, posOfLib = -1;
268       while (libstring.Tokenize(token, from, " "))
269       {
270         ++numOfLibs;
271         lastlib = token;
272         if (token.Contains(fLoadedLib)) posOfLib = numOfLibs;
273       }
274       if (numOfLibs == posOfLib)
275       {
276         gSystem->Unload(fLoadedLib);
277
278         // Check that the library is gone, since Unload() does not return a status code.
279         libstring = gSystem->GetLibraries();
280         if (libstring.Contains(fLoadedLib)) iResult = -EBADF;
281       }
282       else
283       {
284         AliHLTLogging log;
285         log.LoggingVarargs(kHLTLogWarning, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
286           Form("ROOT limitation! Cannot properly cleanup and unload the shared"
287             " library '%s' since another library '%s' was loaded afterwards. Trying to"
288             " unload this library will remove the others and lead to serious memory faults.",
289             fLoadedLib, lastlib.Data()
290         ));
291       }
292     }
293   }
294
295   // Clear the function pointers.
296   fFctCreateReaderFromTCPPort = NULL;
297   fFctCreateReaderFromTCPPorts = NULL;
298   fFctCreateReaderFromBuffer = NULL;
299   fFctDeleteReader = NULL;
300   fFctCreateWriter = NULL;
301   fFctDeleteWriter = NULL;
302
303   return iResult;
304 }