3 /**************************************************************************
4 * This file is property of and copyright by the ALICE HLT Project *
5 * ALICE Experiment at CERN, All rights reserved. *
7 * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 * for The ALICE HLT Project. *
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 **************************************************************************/
19 /// @file AliHLTHOMERLibManager.cxx
20 /// @author Matthias Richter
22 /// @brief dynamic HLT HOMER reader/writer generation and destruction.
26 #include "AliHLTHOMERLibManager.h"
27 #include "AliHLTHOMERReader.h"
28 #include "AliHLTHOMERWriter.h"
29 #include "AliHLTLogging.h"
33 /** ROOT macro for the implementation of ROOT specific class methods */
34 ClassImp(AliHLTHOMERLibManager)
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};
44 AliHLTHOMERLibManager::AliHLTHOMERLibManager()
46 fFctCreateReaderFromTCPPort(NULL),
47 fFctCreateReaderFromTCPPorts(NULL),
48 fFctCreateReaderFromBuffer(NULL),
49 fFctDeleteReader(NULL),
50 fFctCreateWriter(NULL),
51 fFctDeleteWriter(NULL),
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
61 AliHLTHOMERLibManager::~AliHLTHOMERLibManager()
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();
71 AliHLTHOMERReader* AliHLTHOMERLibManager::OpenReader(const char* hostname, unsigned short port )
73 // Open Reader instance for host
74 if (fgLibraryStatus<0) return NULL;
76 fgLibraryStatus=LoadHOMERLibrary();
77 if (fgLibraryStatus <= 0) {
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;
89 AliHLTHOMERReader* AliHLTHOMERLibManager::OpenReader(unsigned int tcpCnt, const char** hostnames, unsigned short* ports)
91 // Open Reader instance for a list of hosts
92 if (fgLibraryStatus<0) return NULL;
94 fgLibraryStatus=LoadHOMERLibrary();
95 if (fgLibraryStatus <= 0) {
99 AliHLTHOMERReader* pReader=NULL;
100 if (fFctCreateReaderFromTCPPorts!=NULL && (pReader=(((AliHLTHOMERReaderCreateFromTCPPorts_t)fFctCreateReaderFromTCPPorts)(tcpCnt, hostnames, ports)))==NULL) {
101 //HLTError("can not create instance of HOMER reader (function %p)", fFctCreateReaderFromTCPPorts);
102 cout << "can not create instance of HOMER reader from port"<<endl;
108 AliHLTHOMERReader* AliHLTHOMERLibManager::OpenReaderBuffer(const AliHLTUInt8_t* pBuffer, int size)
110 // Open Reader instance for a data buffer
111 if (fgLibraryStatus<0) return NULL;
113 fgLibraryStatus=LoadHOMERLibrary();
114 if (fgLibraryStatus <= 0) {
118 AliHLTHOMERReader* pReader=NULL;
119 if (fFctCreateReaderFromBuffer!=NULL && (pReader=(((AliHLTHOMERReaderCreateFromBuffer_t)fFctCreateReaderFromBuffer)(pBuffer, size)))==NULL) {
120 //HLTError("can not create instance of HOMER reader (function %p)", fFctCreateReaderFromBuffer);
126 int AliHLTHOMERLibManager::DeleteReader(AliHLTHOMERReader* pReader)
130 // the actual deletion function is inside the HOMER library
131 if (fgLibraryStatus<0) return fgLibraryStatus;
133 fgLibraryStatus=LoadHOMERLibrary();
134 if (fgLibraryStatus <= 0) {
135 return fgLibraryStatus;
138 if (fFctDeleteReader!=NULL) {
139 ((AliHLTHOMERReaderDelete_t)fFctDeleteReader)(pReader);
145 AliHLTHOMERWriter* AliHLTHOMERLibManager::OpenWriter()
147 // open a Writer instance
148 if (fgLibraryStatus<0) return NULL;
150 fgLibraryStatus=LoadHOMERLibrary();
151 if (fgLibraryStatus <= 0) {
155 AliHLTHOMERWriter* pWriter=NULL;
156 if (fFctCreateWriter!=NULL && (pWriter=(((AliHLTHOMERWriterCreate_t)fFctCreateWriter)()))==NULL) {
157 // HLTError("can not create instance of HOMER writer (function %p)", fFctCreateWriter);
163 int AliHLTHOMERLibManager::DeleteWriter(AliHLTHOMERWriter* pWriter)
165 // see header file for class documentation
166 if (fgLibraryStatus<0) return fgLibraryStatus;
168 fgLibraryStatus=LoadHOMERLibrary();
169 if (fgLibraryStatus <= 0) {
170 return fgLibraryStatus;
173 if (fFctDeleteWriter!=NULL) {
174 ((AliHLTHOMERWriterDelete_t)fFctDeleteWriter)(pWriter);
180 int AliHLTHOMERLibManager::LoadHOMERLibrary()
184 // the actual deletion function is inside the HOMER library
186 const char** library=&fgkLibraries[0];
187 int* refcount = &fgkLibRefCount[0];
189 TString libs = gSystem->GetLibraries();
190 if (libs.Contains(*library) ||
191 (gSystem->Load(*library)) >= 0) {
193 fLoadedLib = *library;
199 } while ((*library)!=NULL);
201 if (iResult>0 && *library!=NULL) {
202 // print compile info
203 typedef void (*CompileInfo)( char*& date, char*& time);
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);
211 if (fFctCreateReaderFromTCPPort==NULL ||
212 fFctCreateReaderFromTCPPorts==NULL ||
213 fFctCreateReaderFromBuffer==NULL ||
214 fFctDeleteReader==NULL ||
215 fFctCreateWriter==NULL ||
216 fFctDeleteWriter==NULL) {
221 if (iResult<0 || *library==NULL) {
222 fFctCreateReaderFromTCPPort=NULL;
223 fFctCreateReaderFromTCPPorts=NULL;
224 fFctCreateReaderFromBuffer=NULL;
225 fFctDeleteReader=NULL;
226 fFctCreateWriter=NULL;
227 fFctDeleteWriter=NULL;
233 int AliHLTHOMERLibManager::UnloadHOMERLibrary()
235 // unload HOMER library
238 if (fLoadedLib != NULL)
240 // Find the corresponding reference count.
241 const char** library=&fgkLibraries[0];
242 int* refcount = &fgkLibRefCount[0];
243 while (*library != NULL)
245 if (strcmp(*library, fLoadedLib) == 0) break;
250 // Decrease the reference count and remove the library if it is zero.
251 if (*refcount >= 0) --(*refcount);
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;
262 Int_t numOfLibs = 0, posOfLib = -1;
263 while (libstring.Tokenize(token, from, " "))
267 if (token.Contains(fLoadedLib)) posOfLib = numOfLibs;
269 if (numOfLibs == posOfLib)
271 gSystem->Unload(fLoadedLib);
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;
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()
290 // Clear the function pointers.
291 fFctCreateReaderFromTCPPort = NULL;
292 fFctCreateReaderFromTCPPorts = NULL;
293 fFctCreateReaderFromBuffer = NULL;
294 fFctDeleteReader = NULL;
295 fFctCreateWriter = NULL;
296 fFctDeleteWriter = NULL;