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. */
24 // see header file for class documentation
26 // refer to README to build package
28 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
32 #include "AliHLTHOMERLibManager.h"
33 #include "AliHLTHOMERReader.h"
34 #include "AliHLTHOMERWriter.h"
35 #include "AliHLTLogging.h"
39 /** ROOT macro for the implementation of ROOT specific class methods */
40 ClassImp(AliHLTHOMERLibManager)
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};
48 AliHLTHOMERLibManager::AliHLTHOMERLibManager()
51 fFctCreateReaderFromTCPPort(NULL),
52 fFctCreateReaderFromTCPPorts(NULL),
53 fFctCreateReaderFromBuffer(NULL),
54 fFctDeleteReader(NULL),
55 fFctCreateWriter(NULL),
56 fFctDeleteWriter(NULL),
59 // see header file for class documentation
61 // refer to README to build package
63 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
66 AliHLTHOMERLibManager::~AliHLTHOMERLibManager()
68 // see header file for class documentation
72 AliHLTHOMERReader* AliHLTHOMERLibManager::OpenReader(const char* hostname, unsigned short port )
74 // see header file for class documentation
75 if (fLibraryStatus<0) return NULL;
77 if (fLibraryStatus==0) {
78 fLibraryStatus=LoadHOMERLibrary();
81 AliHLTHOMERReader* pReader=NULL;
82 if (fFctCreateReaderFromTCPPort!=NULL && (pReader=(((AliHLTHOMERReaderCreateFromTCPPort_t)fFctCreateReaderFromTCPPort)(hostname, port)))==NULL) {
83 //HLTError("can not create instance of HOMER reader (function %p)", fFctCreateReaderFromTCPPort);
89 AliHLTHOMERReader* AliHLTHOMERLibManager::OpenReader(unsigned int tcpCnt, const char** hostnames, unsigned short* ports)
91 // see header file for class documentation
92 if (fLibraryStatus<0) return NULL;
94 if (fLibraryStatus==0) {
95 fLibraryStatus=LoadHOMERLibrary();
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);
106 AliHLTHOMERReader* AliHLTHOMERLibManager::OpenReaderBuffer(const AliHLTUInt8_t* pBuffer, int size)
108 // see header file for class documentation
109 if (fLibraryStatus<0) return NULL;
111 if (fLibraryStatus==0) {
112 fLibraryStatus=LoadHOMERLibrary();
115 AliHLTHOMERReader* pReader=NULL;
116 if (fFctCreateReaderFromBuffer!=NULL && (pReader=(((AliHLTHOMERReaderCreateFromBuffer_t)fFctCreateReaderFromBuffer)(pBuffer, size)))==NULL) {
117 //HLTError("can not create instance of HOMER reader (function %p)", fFctCreateReaderFromBuffer);
123 int AliHLTHOMERLibManager::DeleteReader(AliHLTHOMERReader* pReader)
125 // see header file for class documentation
126 if (fLibraryStatus<0) return fLibraryStatus;
128 if (fLibraryStatus==0) {
129 fLibraryStatus=LoadHOMERLibrary();
132 if (fFctDeleteReader!=NULL) {
133 ((AliHLTHOMERReaderDelete_t)fFctDeleteReader)(pReader);
139 AliHLTHOMERWriter* AliHLTHOMERLibManager::OpenWriter()
141 // see header file for class documentation
142 if (fLibraryStatus<0) return NULL;
144 if (fLibraryStatus==0) {
145 fLibraryStatus=LoadHOMERLibrary();
148 AliHLTHOMERWriter* pWriter=NULL;
149 if (fFctCreateWriter!=NULL && (pWriter=(((AliHLTHOMERWriterCreate_t)fFctCreateWriter)()))==NULL) {
150 // HLTError("can not create instance of HOMER writer (function %p)", fFctCreateWriter);
156 int AliHLTHOMERLibManager::DeleteWriter(AliHLTHOMERWriter* pWriter)
158 // see header file for class documentation
159 if (fLibraryStatus<0) return fLibraryStatus;
161 if (fLibraryStatus==0) {
162 fLibraryStatus=LoadHOMERLibrary();
165 if (fFctDeleteWriter!=NULL) {
166 ((AliHLTHOMERWriterDelete_t)fFctDeleteWriter)(pWriter);
172 int AliHLTHOMERLibManager::LoadHOMERLibrary()
174 // see header file for class documentation
176 const char** library=&fgkLibraries[0];
177 int* refcount = &fgkLibRefCount[0];
179 TString libs = gSystem->GetLibraries();
180 if (libs.Contains(*library)) {
184 if ((gSystem->Load(*library)) >= 0) {
186 fLoadedLib = *library;
192 } while ((*library)!=NULL);
194 if (iResult>0 && *library!=NULL) {
195 // print compile info
196 typedef void (*CompileInfo)( char*& date, char*& time);
197 CompileInfo fctInfo=(CompileInfo)gSystem->DynFindSymbol(*library, "CompileInfo");
201 (*fctInfo)(date, time);
202 if (!date) {date=new Char_t[8]; strcpy(date,"unknown");}
203 if (!time) {time=new Char_t[8]; strcpy(time,"unknown");}
204 //HLTInfo("%s build on %s (%s)", *library, date, time);
206 //HLTInfo("no build info available for %s", *library);
209 fFctCreateReaderFromTCPPort=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERREADER_CREATE_FROM_TCPPORT);
210 fFctCreateReaderFromTCPPorts=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERREADER_CREATE_FROM_TCPPORTS);
211 fFctCreateReaderFromBuffer=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERREADER_CREATE_FROM_BUFFER);
212 fFctDeleteReader=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERREADER_DELETE);
213 fFctCreateWriter=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERWRITER_CREATE);
214 fFctDeleteWriter=(void (*)())gSystem->DynFindSymbol(*library, ALIHLTHOMERWRITER_DELETE);
215 if (fFctCreateReaderFromTCPPort==NULL ||
216 fFctCreateReaderFromTCPPorts==NULL ||
217 fFctCreateReaderFromBuffer==NULL ||
218 fFctDeleteReader==NULL ||
219 fFctCreateWriter==NULL ||
220 fFctDeleteWriter==NULL) {
225 if (iResult<0 || *library==NULL) {
226 fFctCreateReaderFromTCPPort=NULL;
227 fFctCreateReaderFromTCPPorts=NULL;
228 fFctCreateReaderFromBuffer=NULL;
229 fFctDeleteReader=NULL;
230 fFctCreateWriter=NULL;
231 fFctDeleteWriter=NULL;
237 int AliHLTHOMERLibManager::UnloadHOMERLibrary()
239 // see header file for class documentation
242 if (fLoadedLib != NULL)
244 // Find the corresponding reference count.
245 const char** library=&fgkLibraries[0];
246 int* refcount = &fgkLibRefCount[0];
247 while (*library != NULL)
249 if (strcmp(*library, fLoadedLib) == 0) break;
254 // Decrease the reference count and remove the library if it is zero.
255 if (*refcount >= 0) --(*refcount);
258 // Check that the library we are trying to unload is actually the last library
259 // in the gSystem->GetLibraries() list. If not then we must abort the removal.
260 // This is because of a ROOT bug/feature/limitation. If we try unload the library
261 // then ROOT will also wipe all libraries in the gSystem->GetLibraries() list
262 // following the library we want to unload.
263 TString libstring = gSystem->GetLibraries();
264 TString token, lastlib;
266 Int_t numOfLibs = 0, posOfLib = -1;
267 while (libstring.Tokenize(token, from, " "))
271 if (token.Contains(fLoadedLib)) posOfLib = numOfLibs;
273 if (numOfLibs == posOfLib)
275 gSystem->Unload(fLoadedLib);
277 // Check that the library is gone, since Unload() does not return a status code.
278 libstring = gSystem->GetLibraries();
279 if (libstring.Contains(fLoadedLib)) iResult = -EBADF;
284 log.LoggingVarargs(kHLTLogWarning, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
285 Form("ROOT limitation! Cannot properly cleanup and unload the shared"
286 " library '%s' since another library '%s' was loaded afterwards. Trying to"
287 " unload this library will remove the others and lead to serious memory faults.",
288 fLoadedLib, lastlib.Data()
294 // Clear the function pointers.
295 fFctCreateReaderFromTCPPort = NULL;
296 fFctCreateReaderFromTCPPorts = NULL;
297 fFctCreateReaderFromBuffer = NULL;
298 fFctDeleteReader = NULL;
299 fFctCreateWriter = NULL;
300 fFctDeleteWriter = NULL;