00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "TGo4HistogramServer.h"
00017
00018 #include <iostream.h>
00019
00020 #include "TFile.h"
00021
00022 #include "Go4Log/TGo4Log.h"
00023 #include "Go4LockGuard/TGo4LockGuard.h"
00024 #include "Go4Socket/TGo4Socket.h"
00025
00026 #include "TGo4HisConnectorRunnable.h"
00027 #include "TGo4ObjConnectorRunnable.h"
00028 #include "TGo4ObjConnectorTimer.h"
00029 #include "Go4CommandsBase/TGo4CommandInvoker.h"
00030 #include "Go4AnalysisClient/TGo4AnalysisClientImp.h"
00031 #include "Go4Analysis/TGo4AnalysisImp.h"
00032 #include "Go4Analysis/TGo4AnalysisObjectNames.h"
00033 #include "Go4TaskHandler/TGo4TaskManager.h"
00034 #include "Go4Exceptions/Go4Exceptions.h"
00035 #include "Go4ThreadManager/TGo4Thread.h"
00036 #include "Go4ThreadManager/TGo4ThreadManager.h"
00037 #include "Go4ThreadManager/TGo4TerminateException.h"
00038 #include "Go4TaskHandler/TGo4TaskHandler.h"
00039
00040 extern "C"
00041 {
00042
00043 #include "MbsAPI/f_his_hist.h"
00044 }
00045
00046 #include "TGo4MbsHist.h"
00047
00048 const Text_t TGo4HistogramServer::fgcCONTHREADNAME[]="HISTOSERV-";
00049 const Text_t TGo4HistogramServer::fgcSHUTDOWNNAME[]="__HServLast__";
00050 const Text_t TGo4HistogramServer::fgcCOMGETLIST[]="__OServNamesList__";
00051
00052 const Text_t TGo4HistogramServer::fgcOBJTHREADNAME[]="OBJECTSERV-";
00053 const UInt_t TGo4HistogramServer::fguTIMERPERIOD=200;
00054 const Int_t TGo4HistogramServer::fgiOPENWAITCYCLES=100;
00055 const UInt_t TGo4HistogramServer::fguOPENWAITCYCLETIME=500;
00056 const Int_t TGo4HistogramServer::fgiCLOSEWAITCYCLES=100;
00057 const UInt_t TGo4HistogramServer::fguCLOSEWAITCYCLETIME=500;
00058 const Int_t TGo4HistogramServer::fgiCONNECTWAITCYCLES=20;
00059 const UInt_t TGo4HistogramServer::fguCONNECTWAITCYCLETIME=500;
00060
00061 TGo4HistogramServer::TGo4HistogramServer(TGo4AnalysisClient* owner,
00062 const char* servername,
00063 const char* password,
00064 Bool_t useobjectserver)
00065 : fxAnalysisClient(owner), fxThreadHandler(0), fiServerPort(0),
00066 fxTransport(0), fuObjectPort(0), fxConnectTransport(0), fxDisConnectTransport(0),
00067 fuConnectPort(0),
00068 fbConnectRequest(kFALSE), fbDisConnectRequest(kFALSE),
00069 fbConnectIsOpen(kFALSE), fbConnectIsDone(kFALSE),fbConnectIsClose(kTRUE),
00070 fxConnectorTimer(0),
00071 fbUseObjectServer(useobjectserver)
00072 {
00073 TGo4CommandInvoker::Instance();
00074 TGo4CommandInvoker::Register("HistogramServer", this);
00075 if(fbUseObjectServer)
00076 fxTransport = new TGo4Socket(kFALSE);
00077
00078 Int_t result=f_his_server((CHARS*) servername, (CHARS*) password, &fiServerPort);
00079 if(result==COMM__SUCCESS) {
00080
00081 fxServerName = servername;
00082 fxServerPass = password;
00083 TGo4Analysis::Instance()->Message(1,
00084 "Created Histogram server %s on port %d",
00085 servername, fiServerPort);
00086 }
00087 else
00088 {
00089
00090 TGo4Analysis::Instance()->Message(3,
00091 "ERROR %d on creation of Histogram server",
00092 result);
00093 }
00094
00095 const Text_t* ownername;
00096 if(fxAnalysisClient)
00097 {
00098 fxThreadHandler= fxAnalysisClient->GetThreadHandler();
00099 fxAnalysis=fxAnalysisClient->GetAnalysis();
00100 ownername=fxAnalysisClient->GetName();
00101 }
00102 else
00103 {
00104 ownername="never-come-here";
00105 }
00106
00107 if(fbUseObjectServer)
00108 {
00109 fxConnectorTimer= new TGo4ObjConnectorTimer(this,fguTIMERPERIOD);
00110 fxConnectorTimer->TurnOn();
00111 }
00112 if(fxThreadHandler)
00113 {
00114
00115 fxConnectorName = fgcCONTHREADNAME;
00116 fxConnectorName += ownername;
00117
00118 TGo4HisConnectorRunnable* crun = new TGo4HisConnectorRunnable(ConnectorName(), this);
00119 fxThreadHandler->NewThread(ConnectorName(),crun);
00120 fxThreadHandler->Start(ConnectorName());
00121 if(fbUseObjectServer)
00122 {
00123
00124
00125 fxObjectThreadName = fgcOBJTHREADNAME;
00126 fxObjectThreadName += ownername;
00127
00128 TGo4ObjConnectorRunnable* orun = new TGo4ObjConnectorRunnable(ObjectThreadName(), this);
00129 fxThreadHandler->NewThread(ObjectThreadName(), orun);
00130 fxThreadHandler->Start(ObjectThreadName());
00131 }
00132 }
00133 else
00134 {
00135 cerr <<" Histogram Server constructor FATAL ERROR: no threadmanager !!" << endl;
00136 throw TGo4RuntimeException();
00137 }
00138 }
00139
00140 TGo4HistogramServer::TGo4HistogramServer()
00141 : fxAnalysisClient(0), fxThreadHandler(0), fiServerPort(0),
00142 fxTransport(0), fuObjectPort(0), fxConnectTransport(0), fxDisConnectTransport(0),
00143 fcConnectHost(0), fuConnectPort(0),
00144 fbConnectRequest(kFALSE), fbDisConnectRequest(kFALSE),
00145 fbConnectIsOpen(kFALSE), fbConnectIsDone(kFALSE),fbConnectIsClose(kTRUE),
00146 fbUseObjectServer(kFALSE)
00147 {
00148 TGo4CommandInvoker::Instance();
00149 TGo4CommandInvoker::Register("HistogramServer", this);
00150 }
00151
00152
00153 TGo4HistogramServer::~TGo4HistogramServer()
00154 {
00155
00156 if(fbUseObjectServer && fxThreadHandler) fxThreadHandler->Stop(ConnectorName());
00157
00158
00159 INTS4 * pl_all =NULL;
00160 s_his_head * ps_his_head=NULL;
00161 INTS4 l_size=0;
00162 f_his_gethis("localhost" , fiServerPort ,
00163 (char*) fxServerName.Data(),
00164 (char*) fxServerPass.Data(),
00165 (char*) fgcSHUTDOWNNAME,
00166 (s_his_head **)&ps_his_head,
00167 (INTS4 **)&pl_all,
00168 (INTS4 *)&l_size);
00169
00170 if(fxThreadHandler)
00171 {
00172 fxThreadHandler->RemoveThread(ConnectorName());
00174 if(fbUseObjectServer)
00175 {
00176 fxThreadHandler->Stop(ObjectThreadName());
00177
00179
00180
00181 }
00182 }
00183 delete fxConnectorTimer;
00184 f_his_close();
00185
00186 if(fxTransport)
00187 {
00188 fxTransport->Close();
00189 delete fxTransport;
00190 fxTransport=0;
00191 }
00192
00193 }
00194
00195 Int_t TGo4HistogramServer::ServeObjectClient()
00196 {
00197 Int_t rev=ConnectObjectClient();
00198 if(rev<0) return rev;
00199 if(rev==0 && CheckLogin())
00200 {
00201 HandleObjectRequest();
00202 } else {}
00203 DisconnectObjectClient();
00204 return rev;
00205 }
00206
00207 void TGo4HistogramServer::DisconnectObjectClient()
00208 {
00209
00210 SetDisConnect(fxTransport);
00211
00212 WaitForClose();
00213
00214 }
00215
00216 Int_t TGo4HistogramServer::ConnectObjectClient()
00217 {
00218
00219 static Bool_t isfirsttime=kTRUE;
00220
00221 SetConnect(fxTransport, "Server mode does not need hostname", 0);
00222 Int_t waitresult=WaitForOpen();
00223 if(waitresult==-2) return waitresult;
00224 if(waitresult<0)
00225 {
00226
00227 TGo4Log::Debug(" HistogramServer: Negotiation channel open TIMEOUT");
00228 cerr <<" HistogramServer TIMEOUT ERROR opening socket connection !!! Terminating..." << endl;
00229 throw TGo4TerminateException(fxAnalysisClient->GetTask());
00230 }
00231 Int_t count=0;
00232 while(GetObjPort()==0)
00233 {
00234 TGo4Task* task=fxAnalysisClient->GetTask();
00235 if(count>TGo4TaskHandler::fgiPORTWAITCYCLES)
00236 {
00237 TGo4Log::Debug(" HistogramServer: Negotiation port getter TIMEOUT");
00238 cerr <<" HistogramServer TIMEOUT ERROR retrieving port number !!! Terminating..." << endl;
00239 throw TGo4TerminateException(fxAnalysisClient->GetTask());
00240 }
00241 else if(task==0 || task->IsTerminating())
00242 {
00243 return -1;
00244 }
00245 else
00246 {
00247 TGo4Thread::Sleep(TGo4TaskHandler::fguPORTWAITTIME);
00248 ++count;
00249 }
00250 }
00251
00252
00253 if(isfirsttime)
00254 {
00255
00256 TGo4Analysis::Instance()->Message(1,
00257 "Object Server %s is waiting on port %d",
00258 fxServerName.Data(),
00259 fuObjectPort);
00260 isfirsttime=kFALSE;
00261 } else {}
00262 Int_t connectwaitseconds=WaitForConnection();
00263 if(connectwaitseconds<0)
00264 {
00265
00266
00267 return connectwaitseconds;
00268 }
00269 else
00270 {
00271
00272 }
00273
00274 return 0;
00275 }
00276
00277 Bool_t TGo4HistogramServer::CheckLogin()
00278 {
00280
00281
00282 Text_t* recvchar=0;
00283 recvchar=fxTransport->RecvRaw("dummy");
00284 if(recvchar && !strcmp(recvchar,fxServerName.Data()))
00285 {
00286 fxTransport->Send(TGo4TaskHandler::fgcOK);
00287 }
00288 else
00289 {
00290
00291
00292 cerr <<"##### check login with wrong base" << endl;
00293 fxTransport->Send(TGo4TaskHandler::fgcERROR);
00294 DisconnectObjectClient();
00295 return kFALSE;
00296 }
00297
00298 recvchar=fxTransport->RecvRaw("dummy");
00299 if(recvchar && !strcmp(recvchar,fxServerPass.Data()))
00300 {
00301 fxTransport->Send(TGo4TaskHandler::fgcOK);
00302 }
00303 else
00304 {
00305
00306
00307 cerr <<"##### check login with wrong passwd" << endl;
00308 fxTransport->Send(TGo4TaskHandler::fgcERROR);
00309 DisconnectObjectClient();
00310 return kFALSE;
00311 }
00312 return kTRUE;
00313 }
00314
00315 Bool_t TGo4HistogramServer::HandleObjectRequest()
00316 {
00317 Text_t objectname[TGo4ThreadManager::fguTEXTLENGTH];
00318 Text_t* recvchar=0;
00319
00320 recvchar=fxTransport->RecvRaw("dummy");
00321 if(recvchar==0)
00322 {
00323 cerr <<"-----Object server received null character for object request!"<<endl;
00324 return kFALSE;
00325 }
00326 strncpy(objectname, recvchar,TGo4ThreadManager::fguTEXTLENGTH -1);
00327
00328
00329 TObject* object=0;
00330 if(!strcmp(objectname,fgcCOMGETLIST))
00331 {
00332
00333 TGo4LockGuard mainguard;
00334 fxAnalysis->UpdateNamesList();
00335 object=fxAnalysis->GetNamesList();
00336
00337 }
00338 else
00339 {
00340
00341 object=fxAnalysis->GetObject(objectname);
00342
00343 }
00344 return (SendObject(object));
00345 }
00346
00347 Bool_t TGo4HistogramServer::SendObject(TObject* object)
00348 {
00349
00350 Bool_t retval=kTRUE;
00351
00352 TBuffer* rootbuffer=0;
00353 if(object!=0)
00354 {
00355 fxTransport->Send(TGo4TaskHandler::fgcOK);
00356 TGo4LockGuard mainguard;
00357 rootbuffer = new TBuffer(TBuffer::kWrite);
00358 TFile *filsav = gFile;
00359 gFile = 0;
00360 rootbuffer->WriteObject(object);
00361 gFile = filsav;
00362 fxTransport->SendBuffer(rootbuffer);
00363 delete rootbuffer;
00364 }
00365 else
00366 {
00367
00368 fxTransport->Send(TGo4TaskHandler::fgcERROR);
00369 retval=kFALSE;
00370 }
00371 Text_t* recvchar=fxTransport->RecvRaw("dummy");
00372 if(recvchar==0)
00373 {
00374 TGo4Log::Debug(" HistogramServer: null character on finishing object client channel ");
00375 retval=kFALSE;
00376 }
00377 else if(strcmp(recvchar,TGo4TaskHandler::fgcOK))
00378 {
00379 TGo4Log::Debug(" HistogramServer: ERROR on finishing object client channel ");
00380 retval=kFALSE;
00381 }
00382 else
00383 {
00384
00385 }
00386 return retval;
00387 }
00388
00389
00390 void TGo4HistogramServer::SetConnect(TGo4Socket * trans, const char* host, UInt_t port)
00391 {
00392 TRACE((12,"TGo4HistogramServer::SetConnect(TGo4Socket *)",__LINE__, __FILE__));
00393 fxConnectTransport = trans;
00394 fcConnectHost = host;
00395 fuConnectPort = port;
00396 fbConnectRequest = kTRUE;
00397 }
00398
00399 void TGo4HistogramServer::SetDisConnect(TGo4Socket * trans)
00400 {
00401 TRACE((12,"TGo4HistogramServer::SetDisConnect(TGo4Socket *)",__LINE__, __FILE__));
00402 fxDisConnectTransport=trans;
00403 fbDisConnectRequest=kTRUE;
00404 }
00405
00406 Int_t TGo4HistogramServer::TimerConnect()
00407 {
00408 TRACE((12,"TGo4HistogramServer::TimerConnect()",__LINE__, __FILE__));
00409 Int_t rev=0;
00412 if(fbDisConnectRequest)
00413 {
00414 TRACE((15,"TGo4HistogramServer::TimerConnect()--DisConnectRequest",__LINE__, __FILE__));
00415 if(fxDisConnectTransport!=0)
00416 {
00417
00418 fxDisConnectTransport->Close();
00419 fbConnectIsClose=kTRUE;
00420 fbDisConnectRequest=kFALSE;
00421 rev+=1;
00422 }
00423 else
00424 {
00425
00426 rev+=32;
00427 }
00428 }
00429 else
00430 {
00431 TRACE((15,"TGo4HistogramServer::TimerConnect()--NO DisConnectRequest",__LINE__, __FILE__));
00432
00433 rev+=2;
00434 }
00435
00438 if(fbConnectRequest)
00439 {
00440 TRACE((15,"TGo4HistogramServer::TimerConnect()--ConnectRequest",__LINE__, __FILE__));
00441
00442 if(fxConnectTransport!=0)
00443 {
00444 if(!fxConnectTransport->IsOpen())
00445 {
00446 TRACE((10,"TGo4HistogramServer::TimerConnect()--transport is not open",__LINE__, __FILE__));
00447
00448 fbConnectIsOpen=kTRUE;
00449
00450 Int_t result=fxConnectTransport->Open(ConnectHost(), fuConnectPort, kTRUE);
00451 if(result==0)
00452 {
00453 fbConnectIsDone=kTRUE;
00454 fbConnectRequest=kFALSE;
00455 rev+=4;
00456 }
00457 else
00458 {
00459 rev=-4;
00460
00461 }
00462 }
00463 else
00464 {
00465 TRACE((10,"TGo4HistogramServer::TimerConnect()--transport already open",__LINE__, __FILE__));
00466
00467 rev+=8;
00468 }
00469 }
00470 else
00471 {
00472 TRACE((10,"TGo4HistogramServer::TimerConnect()--no transport specified",__LINE__, __FILE__));
00473 rev+=64;
00474 }
00475 }
00476 else
00477 {
00478 TRACE((15,"TGo4HistogramServer::TimerConnect()--NO ConnectRequest",__LINE__, __FILE__));
00479
00480 rev+=16;
00481 }
00482
00483 return rev;
00484 }
00485
00486
00487
00488 Int_t TGo4HistogramServer::WaitForOpen()
00489
00490 {
00491 TRACE((12,"TGo4HistogramServer::WaitForOpen()",__LINE__, __FILE__));
00492 Int_t count=0;
00493 while(!fbConnectIsOpen)
00494 {
00495 TGo4Task* task=fxAnalysisClient->GetTask();
00496 if(count>TGo4HistogramServer::fgiOPENWAITCYCLES)
00497 {
00498 count = -1;
00499 break;
00500 }
00501 else if(task==0 || task->IsTerminating())
00502 {
00503
00504 count = -2;
00505 break;
00506 }
00507 else
00508 {
00509 TGo4Thread::Sleep(TGo4HistogramServer::fguOPENWAITCYCLETIME);
00510 ++count;
00511 }
00512
00513 }
00514 fbConnectIsOpen=kFALSE;
00515 return count;
00516
00517 }
00518
00519
00520 Int_t TGo4HistogramServer::WaitForClose()
00521
00522 {
00523 TRACE((12,"TGo4HistogramServer::WaitForClose()",__LINE__, __FILE__));
00524 Int_t count=0;
00525 while(!fbConnectIsClose)
00526 {
00527
00528 if(count>TGo4HistogramServer::fgiCLOSEWAITCYCLES)
00529 {
00530
00531 count = -1;
00532 break;
00533 }
00534 else
00535 {
00536 TGo4Thread::Sleep(TGo4HistogramServer::fguCLOSEWAITCYCLETIME);
00537 ++count;
00538 }
00539
00540 }
00541 fbConnectIsClose=kFALSE;
00542 return count;
00543
00544 }
00545
00546 Int_t TGo4HistogramServer::WaitForConnection()
00547
00548 {
00549 TRACE((12,"TGo4HistogramServer::WaitForConnection()",__LINE__, __FILE__));
00550 Int_t count=0;
00551 while(!fbConnectIsDone)
00552 {
00553 TGo4Task* task=fxAnalysisClient->GetTask();
00554 if(task==0 || task->IsTerminating())
00555 {
00556
00557 count = -2;
00558 break;
00559 }
00560 else
00561 {
00562 TGo4Thread::Sleep(TGo4HistogramServer::fguCONNECTWAITCYCLETIME);
00563 ++count;
00564 }
00565
00566 }
00567 fbConnectIsDone=kFALSE;
00568 return count;
00569
00570 }
00571
00572
00573 UInt_t TGo4HistogramServer::GetObjPort()
00574 {
00575 if(fxTransport)
00576 {
00577 fuObjectPort = fxTransport->GetPort();
00578 }
00579 return fuObjectPort;
00580 }
00581
00582 ClassImp(TGo4HistogramServer)
00583
00584