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