]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTDimServer.cxx
correcting log message argument after variable type change
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTDimServer.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   AliHLTDimServer.cxx
20     @author Matthias Richter
21     @date   2010-03-10
22     @brief  HLT DIM server implementation
23 */
24
25 #include "AliHLTDimServer.h"
26 #include "TObjArray.h"
27 #include "TSystem.h"
28 #include "TThread.h"
29
30 /** ROOT macro for the implementation of ROOT specific class methods */
31 ClassImp(AliHLTDimServer)
32
33 AliHLTDimServer::AliHLTDimServer()
34   : TNamed()
35   , fServices()
36   , fState(kStateOff)
37   , fpServerThread(NULL)
38   , fUpdatePeriod(10000)
39 {
40   // see header file for class documentation
41   // or
42   // refer to README to build package
43   // or
44   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
45 }
46
47 AliHLTDimServer::AliHLTDimServer(const char* servername)
48   : TNamed(servername, "AliHLTDimServer")
49   , fServices()
50   , fState(kStateOff)
51   , fpServerThread(NULL)
52   , fUpdatePeriod(10000)
53 {
54   // see header file for class documentation
55 }
56
57 AliHLTDimServer::AliHLTDimInterface* AliHLTDimServer::fgpInterface=NULL;
58
59 AliHLTDimServer::~AliHLTDimServer()
60 {
61   // see header file for class documentation
62 }
63
64 int AliHLTDimServer::RegisterService(AliHLTDimService* pService)
65 {
66   // see header file for class documentation
67   if (!pService) return -EINVAL;
68   if (fServices.FindObject(pService)) {
69     AliHLTLogging log;
70     log.LoggingVarargs(kHLTLogError, "AliHLTDimServer", "RegisterService" , __FILE__ , __LINE__ , "duplicate service name %s, skip ...", pService->GetName());
71     return -EEXIST;
72   }
73   fServices.Add(pService);
74   return 0;
75 }
76
77 AliHLTDimServer::AliHLTDimService* AliHLTDimServer::CreateService(enum AliHLTDimServer::AliHLTDimServiceDataType type, const char* name)
78 {
79   // see header file for class documentation
80   AliHLTDimService* service=new AliHLTDimService(type, name);
81   int iResult=RegisterService(service);
82   if (iResult<0) {
83     AliHLTLogging log;
84     log.LoggingVarargs(kHLTLogError, "AliHLTDimServer", "CreateService" , __FILE__ , __LINE__ , "failed to register service %s: %d", name, iResult);
85     if (service) delete service;
86     return NULL;
87   }
88   return service;
89 }
90
91 TObjArray* AliHLTDimServer::CreateServiceGroup(enum AliHLTDimServer::AliHLTDimServiceDataType type, const char* basename, int count)
92 {
93   int iResult=0;
94   TObjArray* pServices=new TObjArray;
95   AliHLTLogging log;
96   if (pServices) {
97     if (basename && count>0) {
98       int digits=1;
99       int i=count;
100       while ((i/=10)>0) digits++;
101       if (digits<9) {
102         log.LoggingVarargs(kHLTLogDebug, "AliHLTDimServer", "CreateServiceGroup" , __FILE__ , __LINE__ , "basename=%s count=%d digits=%d\n", basename, count, digits);
103         int namelen=strlen(basename)+2+digits;
104         char* name=(char*)malloc(namelen);
105         char* format=(char*)malloc(namelen); // this has actually only indirect to do with namelen but its appropriate 
106         if (name && format) {
107           const char* key=strchr(basename, '%');
108           strcpy(format, basename);
109           if (key) {
110             int iPos=(key-basename)+1;
111             if (key[1]=='d') {
112               sprintf(format+iPos, "0*d");
113               iPos+=3;
114             } else {
115               *(format+iPos++)='%';
116               *(format+iPos++)=key[1];
117             }
118             strcpy(format+iPos, &key[2]);
119           } else {
120             sprintf(format+strlen(basename), "_%%0*d");
121           }
122           for (i=0; i<count && iResult>=0; i++) {
123             sprintf(name, format, digits, i);
124             AliHLTDimService* service=new AliHLTDimService(type, name);
125             iResult=RegisterService(service);
126           }
127         } else {
128           iResult=-ENOMEM;
129         }
130         if (name) free(name);
131         if (format) free(format);
132       }
133     }
134   }
135   return pServices;
136 }
137
138 int AliHLTDimServer::UpdateServices()
139 {
140   /// Update all services via the Dim channel
141   return 0;
142 }
143
144 AliHLTDimServer::AliHLTDimInterface* AliHLTDimServer::Interface()
145 {
146   if (!fgpInterface) {
147     fgpInterface=new AliHLTDimInterface;
148     if (fgpInterface) {
149       fgpInterface->Init();
150     }
151   }
152   return fgpInterface;
153 }
154
155 int AliHLTDimServer::Init(const char* dimNameServer)
156 {
157   AliHLTLogging log;
158   const char* myname=GetName();
159   if (myname==NULL || myname[0]==0) {
160     log.LoggingVarargs(kHLTLogError, "AliHLTDimServer", "Init" , __FILE__ , __LINE__ , "can not start without a server name, skipping initialization ...");
161     return -EINVAL;
162   }
163
164   if (Interface()==NULL) return -ENODEV;
165
166   Interface()->DisSetDnsNode(dimNameServer);
167   return 0;
168 }
169
170 int AliHLTDimServer::Reset()
171 {
172   return 0;
173 }
174
175 int AliHLTDimServer::Start()
176 {
177   // start the server in a separate thread
178   int iResult=0;
179   AliHLTLogging log;
180   if (GetState()!=kStateOff) {
181     log.LoggingVarargs(kHLTLogError, "AliHLTDimServer", "Start" , __FILE__ , __LINE__ , "server is not off, currently in state %d", GetState());
182     return -ENOENT;
183   }
184   fpServerThread=new TThread(ServerLoop, (void*)this);
185   if (!fpServerThread) {
186     log.LoggingVarargs(kHLTLogError, "AliHLTDimServer", "Start" , __FILE__ , __LINE__ , "unable to create server thread");
187     return -ENOMEM;
188   }
189   SetState(kStateStarting);
190   fpServerThread->Run();
191   
192   int count=0;
193   const int maxcount=100;
194   const int maxsleepms=1000;
195   while (GetState()==kStateStarting) {
196     if (count++==maxcount) break;
197     gSystem->Sleep(maxsleepms/maxcount);
198   }
199
200   if (GetState()!=kStateRunning) {
201     log.LoggingVarargs(kHLTLogError, "AliHLTDimServer", "Start" , __FILE__ , __LINE__ , "could not start server, currently in state %d", GetState());
202     Reset();
203     iResult=-EFAULT;
204   }
205   return iResult;
206 }
207
208 int AliHLTDimServer::Stop() 
209 {
210   // stop the server thread
211   int iResult=0;
212   AliHLTLogging log;
213   if (GetState()!=kStateRunning) {
214     log.LoggingVarargs(kHLTLogError, "AliHLTDimServer", "Stop" , __FILE__ , __LINE__ , "server is not running, currently in state %d", GetState());
215     return -ENOENT;
216   }
217   SetState(kStateStopping);
218   int count=0;
219   const int maxcount=100;
220   const int maxsleepms=2*fUpdatePeriod;
221   while (GetState()==kStateStopping) {
222     if (count++==maxcount) break;
223     gSystem->Sleep(maxsleepms/maxcount);
224   }
225
226   if (GetState()!=kStateOff) {
227     log.LoggingVarargs(kHLTLogError, "AliHLTDimServer", "Stop" , __FILE__ , __LINE__ , "could not stop server, currently in state %d", GetState());
228     Reset();
229     iResult=-EFAULT;
230   }
231   return iResult;
232 }
233
234 void* AliHLTDimServer::ServerLoop(void* param)
235 {
236   // see header file for class documentation
237   if (!param) return (void*)0;
238   AliHLTDimServer* server=reinterpret_cast<AliHLTDimServer*>(param);
239   return server->ServerLoop();
240 }
241
242 void* AliHLTDimServer::ServerLoop()
243 {
244   // see header file for class documentation
245   if (!Interface()) return (void*)-ENODEV;
246
247   AliHLTLogging log;
248   TIter next(&fServices);
249   TObject* obj=NULL;
250   while ((obj=next())!=NULL) {
251     AliHLTDimService* pService=dynamic_cast<AliHLTDimService*>(obj);
252     if (!pService) continue;
253     TString name=GetName(); name+="_"; name+=pService->GetName();
254     const char* type="";
255     void* buffer=pService->GetLocation();
256     int size=0;
257     switch (pService->GetType()) {
258     case kDataTypeInt:
259       type="I";
260       size=sizeof(int);
261       break;
262     case kDataTypeFloat:
263       type="F";
264       size=sizeof(float);
265       break;
266     case kDataTypeString:
267       log.LoggingVarargs(kHLTLogError, "AliHLTDimServer::AliHLTDimService", "ServerLoop" , __FILE__ , __LINE__ , "ignoring dim service %s: type 'string' not yet implemented", name.Data());
268       break;
269     default:
270       log.LoggingVarargs(kHLTLogError, "AliHLTDimServer::AliHLTDimService", "ServerLoop" , __FILE__ , __LINE__ , "ignoring dim service %s: unknown type %d", name.Data(), pService->GetType());
271     }
272     if (type[0]!=0) {
273       int id=Interface()->DisAddService(name.Data(), type, buffer, size);
274       if (id<0) {
275         log.LoggingVarargs(kHLTLogError, "AliHLTDimServer::AliHLTDimService", "ServerLoop" , __FILE__ , __LINE__ , "failed to add dim service %s: error %d", name.Data(), id);
276       } else {
277          pService->SetId(id);
278       }
279     }
280   }
281
282   SetState(kStateRunning);
283   Interface()->DisStartServing(GetName());
284   while (GetState()==kStateRunning) {
285     gSystem->Sleep(fUpdatePeriod);
286   }
287
288   if (GetState()!=kStateStopping) return (void*)0;
289
290   // cleanup
291   Interface()->DisStopServing();
292   next.Reset();
293   while ((obj=next())!=NULL) {
294     const AliHLTDimService* pService=dynamic_cast<const AliHLTDimService*>(obj);
295     if (!pService || pService->GetId()<0) continue;
296     // int iResult=Interface()->DisRemoveService(pService->GetId());
297     // if (iResult<0) {
298     //   log.LoggingVarargs(kHLTLogError, "AliHLTDimServer::AliHLTDimService", "ServerLoop" , __FILE__ , __LINE__ , "failed to remove dim service %s: error %d", pService->GetName(), iResult);
299     // }
300   }
301
302   SetState(kStateOff);
303
304   return (void*)0;
305 }
306
307 AliHLTDimServer::AliHLTDimService::AliHLTDimService()
308   : TNamed()
309   , fData()
310   , fType(kDataTypeUnknown)
311   , fId(-1)
312 {
313   // see header file for class documentation
314 }
315
316 AliHLTDimServer::AliHLTDimService::AliHLTDimService(enum AliHLTDimServiceDataType type, const char* servicename)
317   : TNamed(servicename, "AliHLTDimService")
318   , fData()
319   , fType(type)
320   , fId(-1)
321 {
322   // see header file for class documentation
323   AliHLTLogging log;
324   switch (fType) {
325   case kDataTypeInt: break;
326   case kDataTypeFloat: break;
327   case kDataTypeString:
328     log.LoggingVarargs(kHLTLogError, "AliHLTDimServer", "AliHLTDimService" , __FILE__ , __LINE__ , "dim service type 'string' not yet implemented");
329     break;
330   default:
331     log.LoggingVarargs(kHLTLogError, "AliHLTDimServer", "AliHLTDimService" , __FILE__ , __LINE__ , "Unknown dim service type %d", fType);
332   };
333 }
334
335 void AliHLTDimServer::AliHLTDimService::Update(AliHLTDimServicePoint_t& sp)
336 {
337   // see header file for class documentation
338   static bool bWarning=true;
339   AliHLTLogging log;
340   switch (fType) {
341   case kDataTypeInt: fData.iVal=sp.iVal; break;
342   case kDataTypeFloat: fData.fVal=sp.fVal; break;
343   case kDataTypeString:
344     if (bWarning) log.LoggingVarargs(kHLTLogError, "AliHLTDimServer::AliHLTDimService", "Update" , __FILE__ , __LINE__ , "Failed to update dim service %s: 'string' not yet implemented", GetName());
345     bWarning=false;
346     break;
347   default:
348     if (bWarning) log.LoggingVarargs(kHLTLogError, "AliHLTDimServer::AliHLTDimService", "Update" , __FILE__ , __LINE__ , "Failed to update dim service %s: unknown type %d", GetName(), fType);
349     bWarning=false;
350   };
351
352   AliHLTDimServer::Interface()->DisUpdateService(fId);
353 }
354
355 AliHLTDimServer::AliHLTDimInterface::AliHLTDimInterface()
356   : AliHLTLogging()
357   , fpDisAddService(NULL)
358   , fpDisRemoveService(NULL)
359   , fpDisUpdateService(NULL)
360   , fpDisStartServing(NULL)
361   , fpDisStopServing(NULL)
362   , fpDisSetDnsNode(NULL)
363 {
364 }
365
366 AliHLTDimServer::AliHLTDimInterface::~AliHLTDimInterface()
367 {
368 }
369
370
371 const char* AliHLTDimServer::AliHLTDimInterface::fgkDimLibraryName="libdim.so";
372 const char* AliHLTDimServer::AliHLTDimInterface::fgkDisAddServiceSymbol="dis_add_service";
373 const char* AliHLTDimServer::AliHLTDimInterface::fgkDisRemoveServiceSymbol="dis_remove_service";
374 const char* AliHLTDimServer::AliHLTDimInterface::fgkDisUpdateServiceSymbol="dis_update_service";
375 const char* AliHLTDimServer::AliHLTDimInterface::fgkDisStartServingSymbol="dis_start_serving";
376 const char* AliHLTDimServer::AliHLTDimInterface::fgkDisStopServingSymbol="dis_stop_serving";
377 const char* AliHLTDimServer::AliHLTDimInterface::fgkDisSetDnsNodeSymbol="dis_set_dns_node";
378
379 int AliHLTDimServer::AliHLTDimInterface::Init()
380 {
381   /// load the dim library and function pointers
382   if (gSystem->Load(fgkDimLibraryName)) {
383     HLTFatal("failed to load dim library: %s", fgkDimLibraryName);
384     return -ENODEV;
385   }
386
387   fpDisAddService=(fctDisAddService)FindSymbol(fgkDimLibraryName, fgkDisAddServiceSymbol);
388   if (!fpDisAddService) return -ENODEV;
389
390   fpDisRemoveService=(fctDisRemoveService)FindSymbol(fgkDimLibraryName, fgkDisRemoveServiceSymbol);
391   if (!fpDisRemoveService) return -ENODEV;
392
393   fpDisUpdateService=(fctDisUpdateService)FindSymbol(fgkDimLibraryName, fgkDisUpdateServiceSymbol);
394   if (!fpDisUpdateService) return -ENODEV;
395
396   fpDisStartServing=(fctDisCharArg)FindSymbol(fgkDimLibraryName, fgkDisStartServingSymbol);
397   if (!fpDisStartServing) return -ENODEV;
398
399   fpDisStopServing=(fctDisNoArg)FindSymbol(fgkDimLibraryName, fgkDisStopServingSymbol);
400   if (!fpDisStopServing) return -ENODEV;
401
402   fpDisSetDnsNode=(fctDisCharArg)FindSymbol(fgkDimLibraryName, fgkDisSetDnsNodeSymbol);
403   if (!fpDisSetDnsNode) return -ENODEV;
404
405   return 0;
406 }
407
408 AliHLTDimServer::fctVoid AliHLTDimServer::AliHLTDimInterface::FindSymbol(const char* library, const char* symbol) const
409 {
410   /// Find symbol in the dim library
411   TString tmp=symbol;
412   fctVoid fctptr=gSystem->DynFindSymbol(library, tmp.Data());
413   if (!fctptr) {
414     // do a 2nd try with appended '_'
415     tmp+="_";
416     fctptr=gSystem->DynFindSymbol(library, tmp.Data());
417   }
418   if (fctptr) return fctptr;
419
420   HLTError("can not find symbol '%s' in %s", symbol, library);
421   return NULL;
422 }