00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "TGo4HistogramServer.h"
00017
00018 #include "Riostream.h"
00019
00020 #include "TFile.h"
00021
00022 #include "TGo4Log.h"
00023 #include "TGo4LockGuard.h"
00024 #include "TGo4Socket.h"
00025 #include "TGo4Buffer.h"
00026
00027 #include "TGo4HisConnectorRunnable.h"
00028 #include "TGo4ObjConnectorRunnable.h"
00029 #include "TGo4ObjConnectorTimer.h"
00030 #include "TGo4CommandInvoker.h"
00031 #include "TGo4AnalysisClientImp.h"
00032 #include "TGo4AnalysisImp.h"
00033 #include "TGo4AnalysisObjectNames.h"
00034 #include "TGo4Task.h"
00035 #include "TGo4TaskManager.h"
00036 #include "TGo4Thread.h"
00037 #include "TGo4ThreadManager.h"
00038 #include "TGo4ThreadHandler.h"
00039 #include "TGo4TerminateException.h"
00040 #include "TGo4TaskHandler.h"
00041
00042 extern "C"
00043 {
00044 #include "f_his_hist.h"
00045 }
00046
00047 const Text_t TGo4HistogramServer::fgcCONTHREADNAME[]="HISTOSERV-";
00048 const Text_t TGo4HistogramServer::fgcSHUTDOWNNAME[]="__HServLast__";
00049 const Text_t TGo4HistogramServer::fgcCOMGETLIST[]="__OServNamesList__";
00050
00051 const Text_t TGo4HistogramServer::fgcOBJTHREADNAME[]="OBJECTSERV-";
00052 const UInt_t TGo4HistogramServer::fguTIMERPERIOD=200;
00053 const Int_t TGo4HistogramServer::fgiOPENWAITCYCLES=100;
00054 const UInt_t TGo4HistogramServer::fguOPENWAITCYCLETIME=500;
00055 const Int_t TGo4HistogramServer::fgiCLOSEWAITCYCLES=100;
00056 const UInt_t TGo4HistogramServer::fguCLOSEWAITCYCLETIME=500;
00057 const Int_t TGo4HistogramServer::fgiCONNECTWAITCYCLES=20;
00058 const UInt_t TGo4HistogramServer::fguCONNECTWAITCYCLETIME=500;
00059
00060 TGo4HistogramServer::TGo4HistogramServer(TGo4AnalysisClient* owner,
00061 const char* servername,
00062 const char* password,
00063 Bool_t useobjectserver)
00064 : fxAnalysisClient(owner), fxThreadHandler(0), fiServerPort(0),
00065 fxTransport(0), fuObjectPort(0), fxConnectTransport(0), fxDisConnectTransport(0),
00066 fuConnectPort(0),
00067 fbConnectRequest(kFALSE), fbDisConnectRequest(kFALSE),
00068 fbConnectIsOpen(kFALSE), fbConnectIsDone(kFALSE),fbConnectIsClose(kTRUE),
00069 fxConnectorTimer(0),
00070 fbUseObjectServer(useobjectserver)
00071 {
00072 TGo4CommandInvoker::Instance();
00073 TGo4CommandInvoker::Register("HistogramServer", this);
00074 if(fbUseObjectServer)
00075 fxTransport = new TGo4Socket(kFALSE);
00076
00077 Int_t result=f_his_server((CHARS*) servername, (CHARS*) password, &fiServerPort);
00078 if(result==COMM__SUCCESS) {
00079 fxServerName = servername;
00080 fxServerPass = password;
00081 TGo4Analysis::Instance()->Message(1,
00082 "Created Histogram server %s on port %d",
00083 servername, fiServerPort);
00084 }
00085 else
00086 {
00087
00088 TGo4Analysis::Instance()->Message(3,
00089 "ERROR %d on creation of Histogram server",
00090 result);
00091 }
00092
00093 const Text_t* ownername;
00094 if(fxAnalysisClient)
00095 {
00096 fxThreadHandler= fxAnalysisClient->GetThreadHandler();
00097 fxAnalysis=fxAnalysisClient->GetAnalysis();
00098 ownername=fxAnalysisClient->GetName();
00099 }
00100 else
00101 {
00102 ownername="never-come-here";
00103 }
00104
00105 if(fbUseObjectServer)
00106 {
00107 fxConnectorTimer= new TGo4ObjConnectorTimer(this,fguTIMERPERIOD);
00108 fxConnectorTimer->TurnOn();
00109 }
00110 if(fxThreadHandler)
00111 {
00112
00113 fxConnectorName = fgcCONTHREADNAME;
00114 fxConnectorName += ownername;
00115
00116 TGo4HisConnectorRunnable* crun = new TGo4HisConnectorRunnable(ConnectorName(), this);
00117 fxThreadHandler->NewThread(ConnectorName(),crun);
00118 fxThreadHandler->Start(ConnectorName());
00119 if(fbUseObjectServer)
00120 {
00121
00122
00123 fxObjectThreadName = fgcOBJTHREADNAME;
00124 fxObjectThreadName += ownername;
00125
00126 TGo4ObjConnectorRunnable* orun = new TGo4ObjConnectorRunnable(ObjectThreadName(), this);
00127 fxThreadHandler->NewThread(ObjectThreadName(), orun);
00128 fxThreadHandler->Start(ObjectThreadName());
00129 }
00130 }
00131 else
00132 {
00133 cerr <<" Histogram Server constructor FATAL ERROR: no threadmanager !!" << endl;
00134 throw TGo4RuntimeException();
00135 }
00136 }
00137
00138 TGo4HistogramServer::TGo4HistogramServer()
00139 : fxAnalysisClient(0), fxThreadHandler(0), fiServerPort(0),
00140 fxTransport(0), fuObjectPort(0), fxConnectTransport(0), fxDisConnectTransport(0),
00141 fcConnectHost(0), fuConnectPort(0),
00142 fbConnectRequest(kFALSE), fbDisConnectRequest(kFALSE),
00143 fbConnectIsOpen(kFALSE), fbConnectIsDone(kFALSE),fbConnectIsClose(kTRUE),
00144 fbUseObjectServer(kFALSE)
00145 {
00146 TGo4CommandInvoker::Instance();
00147 TGo4CommandInvoker::Register("HistogramServer", this);
00148 }
00149
00150
00151 TGo4HistogramServer::~TGo4HistogramServer()
00152 {
00153
00154 if(fbUseObjectServer && fxThreadHandler) fxThreadHandler->Stop(ConnectorName());
00155
00156
00157 INTS4 * pl_all =NULL;
00158 s_his_head * ps_his_head=NULL;
00159 INTS4 l_size=0;
00160 f_his_gethis((char*)"localhost",
00161 fiServerPort ,
00162 (char*) fxServerName.Data(),
00163 (char*) fxServerPass.Data(),
00164 (char*) fgcSHUTDOWNNAME,
00165 (s_his_head **)&ps_his_head,
00166 (INTS4 **)&pl_all,
00167 (INTS4 *)&l_size);
00168
00169 if(fxThreadHandler)
00170 {
00171 fxThreadHandler->RemoveThread(ConnectorName());
00173 if(fbUseObjectServer)
00174 {
00175 fxThreadHandler->Stop(ObjectThreadName());
00176
00178 fxThreadHandler->RemoveThread(ObjectThreadName());
00179
00180 }
00181 }
00182 delete fxConnectorTimer;
00183 f_his_close();
00184
00185 if(fxTransport)
00186 {
00187 fxTransport->Close();
00188 delete fxTransport;
00189 fxTransport=0;
00190 }
00191
00192 TGo4CommandInvoker::UnRegister(this);
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::Get_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::Get_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::Get_fgcOK());
00287 }
00288 else
00289 {
00290
00291
00292 cerr <<"##### check login with wrong base" << endl;
00293 fxTransport->Send(TGo4TaskHandler::Get_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::Get_fgcOK());
00302 }
00303 else
00304 {
00305
00306
00307 cerr <<"##### check login with wrong passwd" << endl;
00308 fxTransport->Send(TGo4TaskHandler::Get_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::Get_fgcOK());
00356 TGo4LockGuard mainguard;
00357 rootbuffer = new TGo4Buffer(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::Get_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::Get_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