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