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