]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/AliHLTHOMERLibManager.cxx
Changes from Svein Lindal
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTHOMERLibManager.cxx
CommitLineData
6580df1c 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"
1b820a65 35#include "AliHLTLogging.h"
6580df1c 36#include "TString.h"
37#include "TSystem.h"
38
39/** ROOT macro for the implementation of ROOT specific class methods */
40ClassImp(AliHLTHOMERLibManager)
41
1b820a65 42// This list must be NULL terminated, since we use it as a marker to identify
43// the end of the list.
44const char* AliHLTHOMERLibManager::fgkLibraries[] = {"libAliHLTHOMER.so", "libHOMER.so", NULL};
45// The size of the list of reference counts must be one less than fgkLibraries.
46int AliHLTHOMERLibManager::fgkLibRefCount[] = {0, 0};
47
6580df1c 48AliHLTHOMERLibManager::AliHLTHOMERLibManager()
49 :
50 fLibraryStatus(0),
a183f221 51 fFctCreateReaderFromTCPPort(NULL),
52 fFctCreateReaderFromTCPPorts(NULL),
6580df1c 53 fFctCreateReaderFromBuffer(NULL),
54 fFctDeleteReader(NULL),
55 fFctCreateWriter(NULL),
1b820a65 56 fFctDeleteWriter(NULL),
57 fLoadedLib(NULL)
6580df1c 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
66AliHLTHOMERLibManager::~AliHLTHOMERLibManager()
67{
68 // see header file for class documentation
1b820a65 69 UnloadHOMERLibrary();
6580df1c 70}
71
a183f221 72AliHLTHOMERReader* 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) {
cfa641b1 83 cout <<"can not create instance of HOMER reader from ports" << endl;
a183f221 84 }
85
86 return pReader;
87}
88
89AliHLTHOMERReader* 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) {
cef34fbe 100 //HLTError("can not create instance of HOMER reader (function %p)", fFctCreateReaderFromTCPPorts);
cfa641b1 101 cout << "can not create instance of HOMER reader from port"<<endl;
a183f221 102 }
103
104 return pReader;
105}
106
18b56222 107AliHLTHOMERReader* AliHLTHOMERLibManager::OpenReaderBuffer(const AliHLTUInt8_t* pBuffer, int size)
6580df1c 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) {
cef34fbe 118 //HLTError("can not create instance of HOMER reader (function %p)", fFctCreateReaderFromBuffer);
6580df1c 119 }
120
121 return pReader;
122}
123
124int 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
140AliHLTHOMERWriter* 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;
77fe3666 150 if (fFctCreateWriter!=NULL && (pWriter=(((AliHLTHOMERWriterCreate_t)fFctCreateWriter)()))==NULL) {
6580df1c 151// HLTError("can not create instance of HOMER writer (function %p)", fFctCreateWriter);
77fe3666 152 }
6580df1c 153
154 return pWriter;
155}
156
157int 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
173int AliHLTHOMERLibManager::LoadHOMERLibrary()
174{
175 // see header file for class documentation
176 int iResult=-EBADF;
1b820a65 177 const char** library=&fgkLibraries[0];
178 int* refcount = &fgkLibRefCount[0];
6580df1c 179 do {
180 TString libs = gSystem->GetLibraries();
1b820a65 181 if (libs.Contains(*library)) {
182 iResult=1;
183 break;
184 }
185 if ((gSystem->Load(*library)) >= 0) {
186 ++(*refcount);
187 fLoadedLib = *library;
6580df1c 188 iResult=1;
189 break;
190 }
1b820a65 191 ++library;
192 ++refcount;
193 } while ((*library)!=NULL);
6580df1c 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) {
a6e0ebfe 200 char* date=0;
201 char* time=0;
6580df1c 202 (*fctInfo)(date, time);
a6e0ebfe 203 if (!date) {date=new Char_t[8]; strcpy(date,"unknown");}
204 if (!time) {time=new Char_t[8]; strcpy(time,"unknown");}
cef34fbe 205 //HLTInfo("%s build on %s (%s)", *library, date, time);
6580df1c 206 } else {
cef34fbe 207 //HLTInfo("no build info available for %s", *library);
6580df1c 208 }
209
d93ec7ca 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);
a183f221 216 if (fFctCreateReaderFromTCPPort==NULL ||
217 fFctCreateReaderFromTCPPorts==NULL ||
218 fFctCreateReaderFromBuffer==NULL ||
219 fFctDeleteReader==NULL ||
220 fFctCreateWriter==NULL ||
221 fFctDeleteWriter==NULL) {
6580df1c 222 iResult=-ENOSYS;
223 } else {
6580df1c 224 }
225 }
226 if (iResult<0 || *library==NULL) {
a183f221 227 fFctCreateReaderFromTCPPort=NULL;
228 fFctCreateReaderFromTCPPorts=NULL;
6580df1c 229 fFctCreateReaderFromBuffer=NULL;
230 fFctDeleteReader=NULL;
231 fFctCreateWriter=NULL;
232 fFctDeleteWriter=NULL;
233 }
234
235 return iResult;
236}
1b820a65 237
238int 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}