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