ALIROOT-5600 - skip non-participating detector modules
[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
c012695e 19/// @file AliHLTHOMERLibManager.cxx
20/// @author Matthias Richter
21/// @date
22/// @brief dynamic HLT HOMER reader/writer generation and destruction.
6580df1c 23
24#include <cerrno>
25#include <cassert>
26#include "AliHLTHOMERLibManager.h"
27#include "AliHLTHOMERReader.h"
28#include "AliHLTHOMERWriter.h"
1b820a65 29#include "AliHLTLogging.h"
6580df1c 30#include "TString.h"
31#include "TSystem.h"
32
33/** ROOT macro for the implementation of ROOT specific class methods */
34ClassImp(AliHLTHOMERLibManager)
35
c012695e 36// global flag of the library status
37int AliHLTHOMERLibManager::fgLibraryStatus=0;
1b820a65 38// This list must be NULL terminated, since we use it as a marker to identify
39// the end of the list.
40const char* AliHLTHOMERLibManager::fgkLibraries[] = {"libAliHLTHOMER.so", "libHOMER.so", NULL};
41// The size of the list of reference counts must be one less than fgkLibraries.
42int AliHLTHOMERLibManager::fgkLibRefCount[] = {0, 0};
43
6580df1c 44AliHLTHOMERLibManager::AliHLTHOMERLibManager()
45 :
a183f221 46 fFctCreateReaderFromTCPPort(NULL),
47 fFctCreateReaderFromTCPPorts(NULL),
6580df1c 48 fFctCreateReaderFromBuffer(NULL),
49 fFctDeleteReader(NULL),
50 fFctCreateWriter(NULL),
1b820a65 51 fFctDeleteWriter(NULL),
52 fLoadedLib(NULL)
6580df1c 53{
c012695e 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
6580df1c 59}
60
61AliHLTHOMERLibManager::~AliHLTHOMERLibManager()
62{
c012695e 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();
6580df1c 69}
70
a183f221 71AliHLTHOMERReader* AliHLTHOMERLibManager::OpenReader(const char* hostname, unsigned short port )
72{
c012695e 73 // Open Reader instance for host
74 if (fgLibraryStatus<0) return NULL;
a183f221 75
8779105a 76 fgLibraryStatus=LoadHOMERLibrary();
77 if (fgLibraryStatus <= 0) {
78 return NULL;
a183f221 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{
c012695e 91 // Open Reader instance for a list of hosts
92 if (fgLibraryStatus<0) return NULL;
a183f221 93
8779105a 94 fgLibraryStatus=LoadHOMERLibrary();
95 if (fgLibraryStatus <= 0) {
96 return NULL;
a183f221 97 }
98
99 AliHLTHOMERReader* pReader=NULL;
100 if (fFctCreateReaderFromTCPPorts!=NULL && (pReader=(((AliHLTHOMERReaderCreateFromTCPPorts_t)fFctCreateReaderFromTCPPorts)(tcpCnt, hostnames, ports)))==NULL) {
cef34fbe 101 //HLTError("can not create instance of HOMER reader (function %p)", fFctCreateReaderFromTCPPorts);
cfa641b1 102 cout << "can not create instance of HOMER reader from port"<<endl;
a183f221 103 }
104
105 return pReader;
106}
107
18b56222 108AliHLTHOMERReader* AliHLTHOMERLibManager::OpenReaderBuffer(const AliHLTUInt8_t* pBuffer, int size)
6580df1c 109{
c012695e 110 // Open Reader instance for a data buffer
111 if (fgLibraryStatus<0) return NULL;
6580df1c 112
8779105a 113 fgLibraryStatus=LoadHOMERLibrary();
114 if (fgLibraryStatus <= 0) {
115 return NULL;
6580df1c 116 }
117
118 AliHLTHOMERReader* pReader=NULL;
119 if (fFctCreateReaderFromBuffer!=NULL && (pReader=(((AliHLTHOMERReaderCreateFromBuffer_t)fFctCreateReaderFromBuffer)(pBuffer, size)))==NULL) {
cef34fbe 120 //HLTError("can not create instance of HOMER reader (function %p)", fFctCreateReaderFromBuffer);
6580df1c 121 }
122
123 return pReader;
124}
125
126int AliHLTHOMERLibManager::DeleteReader(AliHLTHOMERReader* pReader)
127{
c012695e 128 // delete a reader
129
130 // the actual deletion function is inside the HOMER library
131 if (fgLibraryStatus<0) return fgLibraryStatus;
6580df1c 132
8779105a 133 fgLibraryStatus=LoadHOMERLibrary();
134 if (fgLibraryStatus <= 0) {
135 return fgLibraryStatus;
6580df1c 136 }
137
138 if (fFctDeleteReader!=NULL) {
139 ((AliHLTHOMERReaderDelete_t)fFctDeleteReader)(pReader);
140 }
141
142 return 0;
143}
144
145AliHLTHOMERWriter* AliHLTHOMERLibManager::OpenWriter()
146{
c012695e 147 // open a Writer instance
148 if (fgLibraryStatus<0) return NULL;
6580df1c 149
8779105a 150 fgLibraryStatus=LoadHOMERLibrary();
151 if (fgLibraryStatus <= 0) {
152 return NULL;
6580df1c 153 }
154
155 AliHLTHOMERWriter* pWriter=NULL;
77fe3666 156 if (fFctCreateWriter!=NULL && (pWriter=(((AliHLTHOMERWriterCreate_t)fFctCreateWriter)()))==NULL) {
6580df1c 157// HLTError("can not create instance of HOMER writer (function %p)", fFctCreateWriter);
77fe3666 158 }
6580df1c 159
160 return pWriter;
161}
162
163int AliHLTHOMERLibManager::DeleteWriter(AliHLTHOMERWriter* pWriter)
164{
165 // see header file for class documentation
c012695e 166 if (fgLibraryStatus<0) return fgLibraryStatus;
6580df1c 167
8779105a 168 fgLibraryStatus=LoadHOMERLibrary();
169 if (fgLibraryStatus <= 0) {
170 return fgLibraryStatus;
6580df1c 171 }
172
173 if (fFctDeleteWriter!=NULL) {
174 ((AliHLTHOMERWriterDelete_t)fFctDeleteWriter)(pWriter);
175 }
176
177 return 0;
178}
179
180int AliHLTHOMERLibManager::LoadHOMERLibrary()
181{
c012695e 182 // delete a writer
183
184 // the actual deletion function is inside the HOMER library
6580df1c 185 int iResult=-EBADF;
1b820a65 186 const char** library=&fgkLibraries[0];
187 int* refcount = &fgkLibRefCount[0];
6580df1c 188 do {
189 TString libs = gSystem->GetLibraries();
ac3389e3 190 if (libs.Contains(*library) ||
191 (gSystem->Load(*library)) >= 0) {
1b820a65 192 ++(*refcount);
193 fLoadedLib = *library;
6580df1c 194 iResult=1;
195 break;
196 }
1b820a65 197 ++library;
198 ++refcount;
199 } while ((*library)!=NULL);
6580df1c 200
201 if (iResult>0 && *library!=NULL) {
202 // print compile info
203 typedef void (*CompileInfo)( char*& date, char*& time);
6580df1c 204
d93ec7ca 205 fFctCreateReaderFromTCPPort=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERREADER_CREATE_FROM_TCPPORT);
206 fFctCreateReaderFromTCPPorts=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERREADER_CREATE_FROM_TCPPORTS);
207 fFctCreateReaderFromBuffer=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERREADER_CREATE_FROM_BUFFER);
208 fFctDeleteReader=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERREADER_DELETE);
209 fFctCreateWriter=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERWRITER_CREATE);
210 fFctDeleteWriter=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERWRITER_DELETE);
a183f221 211 if (fFctCreateReaderFromTCPPort==NULL ||
212 fFctCreateReaderFromTCPPorts==NULL ||
213 fFctCreateReaderFromBuffer==NULL ||
214 fFctDeleteReader==NULL ||
215 fFctCreateWriter==NULL ||
216 fFctDeleteWriter==NULL) {
6580df1c 217 iResult=-ENOSYS;
218 } else {
6580df1c 219 }
220 }
221 if (iResult<0 || *library==NULL) {
a183f221 222 fFctCreateReaderFromTCPPort=NULL;
223 fFctCreateReaderFromTCPPorts=NULL;
6580df1c 224 fFctCreateReaderFromBuffer=NULL;
225 fFctDeleteReader=NULL;
226 fFctCreateWriter=NULL;
227 fFctDeleteWriter=NULL;
228 }
229
230 return iResult;
231}
1b820a65 232
233int AliHLTHOMERLibManager::UnloadHOMERLibrary()
234{
c012695e 235 // unload HOMER library
1b820a65 236 int iResult=0;
237
238 if (fLoadedLib != NULL)
239 {
240 // Find the corresponding reference count.
241 const char** library=&fgkLibraries[0];
242 int* refcount = &fgkLibRefCount[0];
243 while (*library != NULL)
244 {
245 if (strcmp(*library, fLoadedLib) == 0) break;
246 ++library;
247 ++refcount;
248 }
249
250 // Decrease the reference count and remove the library if it is zero.
251 if (*refcount >= 0) --(*refcount);
252 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 TString libstring = gSystem->GetLibraries();
260 TString token, lastlib;
261 Ssiz_t from = 0;
262 Int_t numOfLibs = 0, posOfLib = -1;
263 while (libstring.Tokenize(token, from, " "))
264 {
265 ++numOfLibs;
266 lastlib = token;
267 if (token.Contains(fLoadedLib)) posOfLib = numOfLibs;
268 }
269 if (numOfLibs == posOfLib)
270 {
271 gSystem->Unload(fLoadedLib);
272
273 // Check that the library is gone, since Unload() does not return a status code.
274 libstring = gSystem->GetLibraries();
275 if (libstring.Contains(fLoadedLib)) iResult = -EBADF;
276 }
277 else
278 {
279 AliHLTLogging log;
280 log.LoggingVarargs(kHLTLogWarning, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
281 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 fLoadedLib, lastlib.Data()
285 ));
286 }
287 }
288 }
289
290 // Clear the function pointers.
291 fFctCreateReaderFromTCPPort = NULL;
292 fFctCreateReaderFromTCPPorts = NULL;
293 fFctCreateReaderFromBuffer = NULL;
294 fFctDeleteReader = NULL;
295 fFctCreateWriter = NULL;
296 fFctDeleteWriter = NULL;
297
298 return iResult;
299}