Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

/Go4TaskHandler/TGo4ServerTask.cxx

Go to the documentation of this file.
00001 //---------------------------------------------------------------
00002 //        Go4 Release Package v2.10-5 (build 21005) 
00003 //                      03-Nov-2005
00004 //---------------------------------------------------------------
00005 //       The GSI Online Offline Object Oriented (Go4) Project
00006 //       Experiment Data Processing at DVEE department, GSI
00007 //---------------------------------------------------------------
00008 //
00009 //Copyright (C) 2000- Gesellschaft f. Schwerionenforschung, GSI
00010 //                    Planckstr. 1, 64291 Darmstadt, Germany
00011 //Contact:            http://go4.gsi.de
00012 //----------------------------------------------------------------
00013 //This software can be used under the license agreements as stated
00014 //in Go4License.txt file which is part of the distribution.
00015 //----------------------------------------------------------------
00016 #include "TGo4ServerTask.h"
00017 
00018 #include <iostream.h>
00019 
00020 #include "TApplication.h"
00021 #include "Go4Log/TGo4Log.h"
00022 #include "Go4LockGuard/TGo4LockGuard.h"
00023 #include "Go4Socket/TGo4Socket.h"
00024 #include "Go4Queue/TGo4BufferQueue.h"
00025 #include "Go4Queue/TGo4ObjectQueue.h"
00026 #include "Go4StatusBase/TGo4Status.h"
00027 #include "Go4CommandsTaskHandler/Go4CommandsTaskHandler.h"
00028 #include "Go4CommandsBase/TGo4CommandInvoker.h"
00029 #include "TGo4TaskManager.h"
00030 #include "TGo4TaskHandler.h"
00031 #include "TGo4ConnectorRunnable.h"
00032 #include "TGo4Master.h"
00033 #include "TGo4Slave.h"
00034 #include <Rtypes.h>
00035 
00036 
00037 const Int_t TGo4ServerTask::fgiOPENWAITCYCLES=100; // wait cycles (100)
00038 const UInt_t TGo4ServerTask::fguOPENWAITCYCLETIME=100; // time in ms (20)
00039 const Int_t TGo4ServerTask::fgiCLOSEWAITCYCLES=100; // wait cycles (100)
00040 const UInt_t TGo4ServerTask::fguCLOSEWAITCYCLETIME=100; // time in ms (20)
00041 const Int_t TGo4ServerTask::fgiCONNECTWAITCYCLES=20; // wait cycles (20)
00042 const UInt_t TGo4ServerTask::fguCONNECTWAITCYCLETIME=200; // time in ms (200)
00043 const UInt_t TGo4ServerTask::fguCONNECTTIMERPERIOD=100; // time in ms (50)
00044 
00045 
00046 const Text_t TGo4ServerTask::fgcLAUNCHPREFSFILE[]="Go4Library/Go4LaunchClientPrefs.txt";
00047 
00048 
00049 TGo4ServerTask::TGo4ServerTask(const char* name,
00050                                UInt_t negotiationport,
00051                                Bool_t blockingmode,
00052                                Bool_t standalone,
00053                                Bool_t autostart,
00054                                Bool_t autocreate,
00055                                Bool_t ismaster)
00056    : TGo4Task(name,blockingmode, autostart,autocreate,ismaster),
00057    fxTaskManager(0),fxCurrentTaskHandler(0),
00058    fxConnectTransport(0), fxDisConnectTransport(0),
00059    fuConnectPort(0), fbKeepServerSocket(kFALSE),
00060    fbConnectRequest(kFALSE), fbDisConnectRequest(kFALSE),
00061    fbConnectIsOpen(kFALSE),fbConnectIsDone(kFALSE), fbConnectIsClose(kFALSE),
00062    fxConnectorTimer(0)
00063 {
00064    Text_t nomen[TGo4ThreadManager::fguTEXTLENGTH];
00065    // task manager aggregate:
00066    snprintf(nomen,TGo4ThreadManager::fguTEXTLENGTH -1, "TaskManager of %s", name);
00067    fxTaskManager= new TGo4TaskManager(nomen,this,negotiationport);
00068  
00069    if(negotiationport!=42)
00070       {
00071          // connector runnable:
00072          snprintf(nomen,TGo4ThreadManager::fguTEXTLENGTH -1,"ConnectorRunnable of %s", name);
00073          TGo4ConnectorRunnable* conny = new TGo4ConnectorRunnable(nomen,this);
00074          snprintf(nomen,TGo4ThreadManager::fguTEXTLENGTH -1, "CONNECTOR-%s", name);
00075          fxConnectorName=nomen;
00076          fxWorkHandler->NewThread(GetConnectorName(), conny);
00077       }
00078       else  {} // do not start connector port in local mode <- nameservice problems without wan!
00079  
00080    TGo4CommandInvoker::Instance(); // make sure a command invoker exists
00081    TGo4CommandInvoker::Register("ServerTask", this);
00082    fxConnectorTimer= new TGo4TaskConnectorTimer(this,fguCONNECTTIMERPERIOD);
00083    fxConnectorTimer->TurnOn();
00084    if(standalone)
00085       {
00086          Launch(); // create threads, start application control timer
00087       }
00088    else
00089       {
00090          // subclass must call Launch at end of its ctor
00091       }
00092 }
00093 
00094 
00095 TGo4ServerTask::~TGo4ServerTask()
00096 {
00097    if (GetWorkHandler()) GetWorkHandler()->CancelAll();
00098    delete fxConnectorTimer;
00099    delete fxTaskManager;
00100 }
00101 
00102 Bool_t TGo4ServerTask::RemoveClient(const char* name, Bool_t clientwait, Bool_t isterminating)
00103 {
00104    Bool_t rev=kTRUE;
00105    TGo4TaskHandler* taskhandler=0;
00106    if(name && strstr(name,"current"))
00107       {
00108          //cout <<"RemoveClient on current taskhandler "<<name << endl;
00109          taskhandler=GetCurrentTaskHandler();               
00110       }
00111    else
00112       {
00113          //cout <<"RemoveClient for taskhandler "<<name << endl;
00114          taskhandler=GetTaskHandler(name);
00115       }
00116    if(taskhandler==0)
00117       {
00118          // no such taskhandler for name
00119          TGo4Log::Debug(" ServerTask -- RemoveClient FAILED, no client %s !!! ",
00120                   name);
00121          rev=kFALSE;
00122       }
00123    else // if(taskhandler==0)
00124       {
00125        TGo4Log::Debug(" ServerTask -- removing client task %s ",name);
00126        // first stop all user threads waiting on or writing into the data queues
00127       StopWorkThreads();      
00128       if(clientwait)
00129          {
00130          // normal mode: handshake with client to be removed
00131 
00132             // send quit command to client, client will send dummy objects back
00133             // to release waiting sockets
00134             // then client will request a disconnect action from the connector runnable
00135             if(IsMaster())
00136                SubmitEmergencyCommand(kComQuit); // master quits client when removing
00137             else      
00138                SubmitEmergencyData(kComQuit, taskhandler->GetName()); // client data runnable must handle quit request of server! 
00139             TGo4Log::Debug(" Server Task --  Waiting for client %s disconnection...",taskhandler->GetName());
00140             Int_t removeresult=fxTaskManager->WaitForClientRemoved();
00141                            // disconnection is done by connector
00142                            // thread using task manager methods
00143             switch(removeresult)
00144                {
00145                case -1:
00146                   // timeout
00147                   TGo4Log::Debug(" !!! Server Task -- client remove wait TIMEOUT !!!  ");
00148                   rev=fxTaskManager->DisConnectClient(taskhandler->GetName(),kFALSE); // do not wait for client ok
00149                   cout <<"client remove wait TIMEOUT after DisConnectClient " << endl;
00150                   break;
00151 
00152                case -2:
00153                   // we are terminating the server
00154                   TGo4Log::Debug(" !!! Server Task -- client remove aborted for TERMINATION MODE !!!  ");
00155                   rev=kFALSE;
00156                   break;
00157 
00158                default:
00159                   // all right
00160                   TGo4Log::Debug(" Server Task -- waited %d cycles until client was removed. ",removeresult);
00161                   rev=kTRUE;
00162                   break;
00163 
00164                      }
00165          } // if(clientwait)
00166       else
00167          {
00168          // no communication with client, just disconnect without waiting
00169          TGo4Log::Debug(" !!! Server Task -- removing client %s without waiting...  ",
00170                                     taskhandler->GetName());
00171          SendStopBuffers(taskhandler->GetName());
00172          rev= (fxTaskManager->DisConnectClient(taskhandler->GetName(),kFALSE)==0); // do not wait
00173          }
00174       if(!isterminating) StartWorkThreads();
00175    } // else if(taskhandler==0)
00176    return rev;
00177 }
00178 
00179 Int_t TGo4ServerTask::RemoveAllClients()
00180 {
00181    Int_t rev=0; // return value is number of removed clients
00182    //cout <<"TTTTTTTT TGo4ServerTask::RemoveAllClients" << endl;
00184    TGo4TaskHandler* taskhandler=0;
00185    TObjArray names;
00186    Bool_t reset=kTRUE;
00187    while((taskhandler=fxTaskManager->NextTaskHandler(reset)) !=0)
00188       {
00189          reset=kFALSE;
00190          //cout <<"adding name "<<taskhandler->GetName() << endl;
00191          names.AddLast(new TNamed(taskhandler->GetName(), "title"));
00192       }
00193    TIter niter(&names);
00194    TObject* nomen=0;
00195    while((nomen =niter.Next()) !=0)
00196       {
00197          //cout <<"removing th "<<nomen->GetName() << endl;
00198          RemoveClient(nomen->GetName(),kTRUE,kTRUE);
00199          rev++;
00200       }
00201    names.Delete();   
00202    // end iteration
00203    return rev;
00204 }
00205 
00206 
00207 Bool_t TGo4ServerTask::RemoveCurrentClient()
00208 {
00209    Bool_t rev=kTRUE;
00210    TGo4TaskHandler* taskhandler=GetCurrentTaskHandler();
00211    if(taskhandler!=0)
00212       {
00213          // we have a current client, remove it
00214          TGo4Log::Debug(" Server task -- removing current client %s ",taskhandler->GetName());
00215          rev = RemoveClient(taskhandler->GetName());
00216       }
00217    else
00218       {
00219          rev=kFALSE;
00220       }
00221    return rev;
00222 }
00223 
00224 void TGo4ServerTask::SetCurrentTask(const char* name)
00225 {
00226    //cout <<"server task setting current task to "<<name << endl;
00227    TGo4TaskHandler* han=0;
00228    if(fxTaskManager==0)
00229       {
00230          TGo4Log::Debug(" TGo4ServerTask ''%s'' ERROR- task manager not existing!!! ");
00231       }
00232    else
00233       {
00234          // first stop all user threads waiting on or writing into the data queues
00235          if(IsWorkStopped())
00236             {
00237                // Working threads have already been stopped
00238                // maybe by RemoveClient method.
00239                // We do nothing, since the current taskhandler is not
00240                // reset yet and any access to current task in the derived
00241                // _user_ method would crash the program!
00242             }
00243          else // if(IsWorkStopped())
00244             {
00245                // work has not been stopped, we do that
00246                StopWorkThreads();
00247             } // else if(fbWorkIsStopped)
00248       {
00249            if(name==0)
00250                {
00251                   // zero name given, set pointer to last handler still in list
00252                      fxCurrentTaskHandler=fxTaskManager->GetLastTaskHandler();
00253 //                     cout << "**** set current th from get lastth:"<< fxCurrentTaskHandler <<endl;
00254                }
00255             else // if(name==0)
00256                {
00257                // name specified, search for it
00258                han=fxTaskManager->GetTaskHandler(name);
00259                if(han)
00260                   {
00261                      fxCurrentTaskHandler=han;
00262 //                     cout << "**** set current th from name:"<< fxCurrentTaskHandler <<endl;
00263                   }
00264                else // if(han)
00265                   {
00266                       TGo4Log::Debug(" ServerTask: FAILED setting current task to %s-- no such client! ",name);
00267                   } // else if(han)
00268                } // else if(name==0)
00269 
00270       } // TGo4LockGuard
00271        // finally, start user threads again
00272          StartWorkThreads();
00273       } // else if(fxTaskManager==0)
00274 }
00275 
00276 
00277 TGo4TaskHandler* TGo4ServerTask::GetTaskHandler(const char* name)
00278 {
00279    return (fxTaskManager->GetTaskHandler(name));
00280 }
00281 
00282 TGo4TaskHandler* TGo4ServerTask::GetTaskHandler()
00283 {
00284    return (GetCurrentTaskHandler());
00285 }
00286 
00287 TGo4TaskHandler* TGo4ServerTask::GetCurrentTaskHandler()
00288 {
00289    return fxCurrentTaskHandler;
00290 }
00291 
00292 TGo4TaskManager* TGo4ServerTask::GetTaskManager()
00293 {
00294    return fxTaskManager;
00295 }
00296 
00297 void TGo4ServerTask::SetConnect(TGo4Socket * trans, const char* host, UInt_t port, Bool_t keepserv)
00298 {
00299    fxConnectTransport=trans;
00300    fxConnectHost=host;
00301    fuConnectPort=port;
00302    fbConnectRequest=kTRUE;
00303    fbKeepServerSocket=keepserv;
00304 }
00305 
00306 void TGo4ServerTask::SetDisConnect(TGo4Socket * trans)
00307 {
00308    fxDisConnectTransport=trans;
00309    fbDisConnectRequest=kTRUE;
00310 }
00311 
00312 Int_t TGo4ServerTask::TimerConnect()
00313 {
00314    Int_t rev=0;
00317    if(fbDisConnectRequest)
00318       {
00319          if(fxDisConnectTransport!=0)
00320             {
00321                // we have a transport instance to disconnect
00322                fxDisConnectTransport->Close();
00323                //delete fxDisConnectTransport; // new
00324                //cout << "++++++++Timer closed transport"<<endl;
00325                fbConnectIsClose=kTRUE;
00326                fbDisConnectRequest=kFALSE; // we served the request, reset it
00327             rev+=1;
00328             }
00329          else
00330             {
00331                // error, zero pointer given
00332                rev+=32;
00333             }
00334       }
00335    else 
00336       {
00337          // no open request, continue
00338          rev+=2;
00339       }
00340 
00343    if(fbConnectRequest)
00344       {
00345          // timer shall open a transport as server
00346       if(fxConnectTransport!=0)
00347          {
00348 
00349             if(!fxConnectTransport->IsOpen())
00350                {
00351                   // transport is not open, so do it
00352                   fbConnectIsOpen=kTRUE; // tell connector thread that we try to open
00353                   Int_t result=fxConnectTransport->Open(GetConnectHost(), fuConnectPort, fbKeepServerSocket);
00354                   if(result==0)
00355                      {
00356                         fbConnectIsDone=kTRUE; // tell connector thread we returned from open
00357                         fbConnectRequest=kFALSE; // we served the request, reset it
00358                         fbKeepServerSocket=kFALSE; // reset keep server socket flag
00359                         rev+=4;
00360                      }
00361                   else
00362                      {
00363                         rev=-4;
00364                         // open was not finished, we poll once again...
00365                      }
00366                }
00367             else
00368                {
00369                   // transport was already open, do nothing
00370                   rev+=8;
00371                }
00372          } // if(fxConnectTransport!=0)
00373       else
00374          {
00375                rev+=64;
00376                // no Transport specified: create raw server for negotiation port
00377                //fxConnectTransport=new TGo4Socket("Server",3);
00378                //cout << "(((((( timer created new raw server transport"<<endl;
00379          }
00380       } 
00381    else
00382       {
00383          // no open request, continue
00384          rev+=16;
00385       }
00386    return rev;
00387 }
00388 
00389 Int_t TGo4ServerTask::WaitForOpen()
00390 {
00391    Int_t count=0;
00392    while(!fbConnectIsOpen)
00393       {
00394          if(count>TGo4ServerTask::fgiOPENWAITCYCLES)
00395             {
00396                count = -1; // timeout
00397                break;
00398             }
00399          else
00400             {
00401             TGo4Thread::Sleep(TGo4ServerTask::fguOPENWAITCYCLETIME);
00402             ++count;
00403             }
00404       //cout << "*****WaitForOpen()"<<endl;
00405       }
00406    fbConnectIsOpen=kFALSE; //  reset for next time
00407    return count;
00408 }
00409 
00410 
00411 Int_t TGo4ServerTask::WaitForClose()
00412 {
00413    Int_t count=0;
00414    while(!fbConnectIsClose)
00415       {
00416           if(count>TGo4ServerTask::fgiCLOSEWAITCYCLES)
00417             {
00418                count = -1; // timeout
00419                break;
00420             }
00421          else
00422             {
00423                TGo4Thread::Sleep(TGo4ServerTask::fguCLOSEWAITCYCLETIME);
00424                ++count;
00425          }
00426       //cout << "*****WaitForClose() "<<count<< endl;
00427       }
00428    fbConnectIsClose=kFALSE; //  reset for next time
00429    return count;
00430 }
00431 
00432 Int_t TGo4ServerTask::WaitForConnection()
00433 {
00434    Int_t count=0;
00435    while(!fbConnectIsDone)
00436       {
00437          if(IsTerminating())
00438             {
00439                count = -2; // termination mode
00440                break;
00441             }
00442 // timeout would affect the permanent connector port Open , we skip this
00443 //         else if(count>TGo4ServerTask::fgiCONNECTWAITCYCLES)
00444 //            {
00445 //               count = -1; // timeout
00446 //               break;
00447 //            }
00448          else
00449             {
00450                TGo4Thread::Sleep(TGo4ServerTask::fguCONNECTWAITCYCLETIME);
00451                ++count;
00452             }
00453          //cout << "*****WaitForConnection()"<<endl;
00454       }
00455    fbConnectIsDone=kFALSE; //  reset for next time
00456    return count;
00457 }
00458 
00459 TGo4Socket* TGo4ServerTask::GetConnectTransport()
00460 {
00461    return fxConnectTransport;
00462 }
00463 
00464 TGo4BufferQueue* TGo4ServerTask::GetCommandQueue(const char* name)
00465 {
00466    TGo4BufferQueue* queue=0;
00467    TGo4TaskHandler* currenttask=0;
00468    if(name==0 || strstr(name,"current"))
00469       currenttask=GetCurrentTaskHandler(); // find out the current client
00470    else
00471       currenttask=GetTaskHandler(name); // find out destination client by name
00472    if(currenttask)
00473          queue=dynamic_cast<TGo4BufferQueue*> (currenttask->GetCommandQueue());
00474    return queue;
00475 }
00476 
00477 TGo4BufferQueue * TGo4ServerTask::GetStatusQueue(const char* name)
00478 {
00479    TGo4BufferQueue* queue=0;
00480    TGo4TaskHandler* currenttask=0;
00481    if(name==0)
00482       currenttask=GetCurrentTaskHandler(); // find out the current client
00483    else
00484       currenttask=GetTaskHandler(name); // find out destination client by name
00485    if(currenttask)
00486          queue=dynamic_cast<TGo4BufferQueue*> (currenttask->GetStatusQueue());
00487    return queue;
00488 }
00489 
00490 
00491 TGo4BufferQueue * TGo4ServerTask::GetDataQueue(const char* name)
00492 {
00493    TGo4BufferQueue* queue=0;
00494    TGo4TaskHandler* currenttask=0;
00495    if(name==0 || strstr(name,"current"))
00496       currenttask=GetCurrentTaskHandler(); // find out the current client
00497    else
00498       currenttask=GetTaskHandler(name); // find out destination client by name
00499    if(currenttask)
00500          queue=dynamic_cast<TGo4BufferQueue*> (currenttask->GetDataQueue());
00501    return queue;
00502 
00503 }
00504 
00505 TGo4Command* TGo4ServerTask::NextCommand()
00506 {
00507 if(IsMaster()) return 0;
00508 TGo4Command* com=0;
00509 TGo4TaskHandler* han=0;
00510 Bool_t reset=kTRUE;
00511 TGo4LockGuard taskmutex(fxTaskManager->GetMutex()); 
00512 while((han=fxTaskManager->NextTaskHandler(reset))!=0)
00513    {
00514        reset=kFALSE;
00515        TGo4BufferQueue * comq=dynamic_cast<TGo4BufferQueue*> (han->GetCommandQueue());
00516        if(comq==0) continue; //NEVER COME HERE!
00517        if(!comq->IsEmpty()) // prevent waiting on queue
00518          {
00519              com= dynamic_cast<TGo4Command*>(comq->WaitObjectFromBuffer());
00520              if(com) 
00521                {
00522                   com->SetTaskName(han->GetName());
00523                   com->SetMode(han->GetRole()); 
00524                   return com;
00525                }
00526          }
00527    } // while
00528 return com;   
00529 }
00530 
00531 void TGo4ServerTask::SendStatus(TGo4Status * stat, const char* receiver)
00532 {
00533 if(IsMaster()) return;
00534 if(stat==0) return;
00535 if(receiver!=0) 
00536    {
00537       TGo4Task::SendStatus(stat,receiver);
00538    }
00539 else
00540    {
00541       // send status to all 
00542       TGo4LockGuard taskmutex(fxTaskManager->GetMutex()); 
00543       TGo4TaskHandler* han=0;
00544       Bool_t reset=kTRUE;
00545       while((han=fxTaskManager->NextTaskHandler(reset))!=0)
00546          {
00547             reset=kFALSE;
00548             TGo4BufferQueue * statq=dynamic_cast<TGo4BufferQueue*> (han->GetStatusQueue());
00549             if(statq==0) continue; //NEVER COME HERE!
00550             TGo4Log::Debug(" Task - sending status %s to task %s", stat->ClassName(), han->GetName());
00551             statq->AddBufferFromObject(stat);
00552          }// while
00553    } // if(receiver)     
00554 }
00555 
00556 void TGo4ServerTask::SendStatusBuffer()
00557 {
00558 if(IsMaster()) return;
00559 TGo4LockGuard statguard(fxStatusMutex); // do not send during buffer update
00560 TGo4LockGuard taskmutex(fxTaskManager->GetMutex()); // protect task list
00561 TGo4TaskHandler* han=0;
00562 Bool_t reset=kTRUE;
00563 while((han=fxTaskManager->NextTaskHandler(reset))!=0)
00564    {
00565       reset=kFALSE;
00566       TGo4BufferQueue * statq=dynamic_cast<TGo4BufferQueue*> (han->GetStatusQueue());
00567       if(statq==0) continue; //NEVER COME HERE!
00568       TGo4Log::Debug(" Task - sending status buffer to task %s", han->GetName());
00569       statq->AddBuffer(fxStatusBuffer,kTRUE);
00570    }// while
00571 }
00572 
00573 
00574 
00575 Bool_t TGo4ServerTask::StartConnectorThread()
00576 {
00577    Bool_t rev=kTRUE;
00578    rev= ( GetWorkHandler()->Start( GetConnectorName() ) );
00579       //cout << "ServerTask started connector thread"<<endl;
00580    return rev;
00581 }
00582 
00583 Bool_t TGo4ServerTask::StopConnectorThread()
00584 {
00585    Bool_t rev=kTRUE;
00586    rev= ( GetWorkHandler()->Stop( GetConnectorName() ) ); // unset running flag
00587    // now establish a dummy connection to our own server to release the listen socket:
00588    const char* host = gSystem->HostName();
00589    Int_t negotiationport=fxTaskManager->GetNegotiationPort();
00590    TGo4Socket* connector= new TGo4Socket(kTRUE); // raw socket transport
00591       //cout << "host:"<<host<<" , port:" << negotiationport <<endl;
00592    connector->Open(host,negotiationport); // open connection to server's connector runnable
00593    connector->Send(TGo4TaskHandler::fgcERROR); // force server to stop
00594    connector->Close();
00595    delete connector;
00596       //cout << "ServerTask stopped connector thread"<<endl;
00597    return rev;
00598 }
00599 
00600 
00601 Bool_t TGo4ServerTask::ConnectorThreadIsStopped()
00602 {
00603    Bool_t rev=kTRUE;
00604    TGo4Thread* conny= GetWorkHandler()->GetThread(GetConnectorName());
00605    rev= conny->IsWaiting();
00606    return rev;
00607 }
00608 
00609 void TGo4ServerTask::Quit()
00610 {
00611    TGo4Log::Debug(" ServerTask Quit -- removing all connected clients ");
00612    SendStatusMessage(2,kTRUE,"ServerTask %s is shutting down now! All clients are removed...",GetName());
00613    RemoveAllClients();
00614    //StopWorkThreads(); // are re-started after last client is removed...
00615    WakeCommandQueue(TGo4Task::fgiTERMID); // will stop local command thread, and remote 
00616    Terminate(!IsMaster()); // terminate only slave server here!   
00617 }
00618 
00619 
00620 void TGo4ServerTask::Shutdown()
00621 {
00622    TGo4Log::Debug(" ServerTask Shutdown without disconnect waiting");
00623    SendStatusMessage(2,kTRUE,"ServerTask %s is shutting down now! All clients are removed...",GetName());
00624    TGo4Thread::Sleep(10*fguCONNECTTIMERPERIOD); // wait 1 s to broadcast shutdown message before terminating...
00625    StopWorkThreads(); 
00626    WakeCommandQueue(TGo4Task::fgiTERMID); // will stop local command thread, and remote 
00627    Terminate(!IsMaster()); // need this to set term state to disable socket exceptions   
00628    TGo4Slave* slave=GetSlave();
00629    if(slave) 
00630       {
00631          slave->Stop(); // to execute analysis postloop. 
00632                         // We are within main thread here, i.e. it never stops before termination!
00633          slave->SetTask(0,kFALSE); // otherwise owner dtor will delete us... 
00634          delete slave;   //call dtors of analysis framework
00635       }
00636    gApplication->Terminate(); // do not wait until appctrl timer terminates us
00637 }
00638 
00639 
00640 
00641 
00642 Int_t TGo4ServerTask::LaunchClient(const char* name, 
00643                                 const char* remotehost, 
00644                                 const char* remotedir, 
00645                                 const char* remotecommand, Int_t mode)
00646 {
00647    Int_t rev = 0;
00648    Text_t commandstring[5*TGo4ThreadManager::fguTEXTLENGTH];
00649    Text_t formatstring[2*TGo4ThreadManager::fguTEXTLENGTH];
00650    Text_t filename[2*TGo4ThreadManager::fguTEXTLENGTH];
00651    Text_t shcom[TGo4ThreadManager::fguTEXTLENGTH];
00652   Text_t serverdisplay[TGo4ThreadManager::fguTEXTLENGTH];
00653    if(mode & kSecureShell)
00654       sprintf(shcom,"ssh ");
00655    else
00656       sprintf(shcom,"rsh -n");
00657    const Text_t* serverhost=gSystem->HostName();
00658    const Text_t* sdisplay=gSystem->Getenv("DISPLAY");
00659    const Text_t* go4system=gSystem->Getenv("GO4SYS");
00660    const Text_t* rootsystem=gSystem->Getenv("ROOTSYS");
00661    const Text_t* path=gSystem->Getenv("PATH");
00662    const Text_t* ldpath=gSystem->Getenv("LD_LIBRARY_PATH");
00663    UInt_t negport=GetTaskManager()->GetNegotiationPort();
00664    snprintf(serverdisplay, 2*TGo4ThreadManager::fguTEXTLENGTH,"-display %s",sdisplay);
00665    if(remotehost==0)
00666       {
00667          remotehost="localhost";
00668       }
00669    else
00670       { }
00671    if(GetMaster()) GetMaster()->SetSlave(remotehost,shcom,remotecommand);
00672 
00673 //  read command/formatting string from file:
00674    snprintf(filename, 2*TGo4ThreadManager::fguTEXTLENGTH,
00675            "%s/%s",go4system, TGo4ServerTask::fgcLAUNCHPREFSFILE);
00676    ifstream launchprefs(filename);
00677    if(!launchprefs)
00678       {
00679          TGo4Log::Debug(" ServerTask -- ERROR: Preferences file %s not existing, could not launch client ",
00680                   filename);
00681          return -1;
00682       }
00683    StopConnectorThread(); // disable server socket listen, would be taken by child
00684    while(!ConnectorThreadIsStopped())
00685       {
00686          TGo4Log::Debug(" ServerTask -- waiting for connector thread to be stopped...");
00687          TGo4Thread::Sleep(500);
00688       }
00689 
00690    TGo4Log::Debug(" ServerTask -- Launching new client process %s on host %s, port %d ",
00691          name, remotehost, negport);
00692 
00693   launchprefs.getline(formatstring, 2*TGo4ThreadManager::fguTEXTLENGTH, '\n' ); // read first line
00694   if((mode & kGuiEmbed) && GetMaster()!=0)
00695     {
00696     //   cout << "mode & kGuiEmbed  is true" << endl;
00697      // run without external xterm, but within the same shell window as the gui:
00698      // use formatstring of first line here
00699          snprintf(commandstring,
00700               5*TGo4ThreadManager::fguTEXTLENGTH-1,
00701               formatstring,
00702               shcom, remotehost, go4system, rootsystem,
00703                  path, ldpath, remotedir, remotecommand, name, serverhost, negport);
00704 
00705         GetMaster()->StartSlaveWindow(commandstring);
00706     }
00707     else
00708     {
00709             if (mode & kSecureShell) {
00710                // start xterm window and display it on the local desktop (display of the gui)
00711                 //cout << "kSecureShell " << kSecureShell << endl;
00712                launchprefs.getline(formatstring, 2*TGo4ThreadManager::fguTEXTLENGTH, '\n'); // use second line
00713                snprintf(commandstring,
00714                  5*TGo4ThreadManager::fguTEXTLENGTH-1,
00715                  formatstring,
00716                  shcom, remotehost, "", name, remotehost, go4system, rootsystem,
00717                     path, ldpath, remotedir, remotecommand, name, serverhost, negport);
00718             }else {
00719             //cout << " ELSE " << kSecureShell  << endl;
00720            launchprefs.getline(formatstring, 2*TGo4ThreadManager::fguTEXTLENGTH, '\n'); // use third  line
00721                snprintf(commandstring,
00722                  5*TGo4ThreadManager::fguTEXTLENGTH-1,
00723                  formatstring,
00724                  shcom, remotehost, serverdisplay, name, remotehost, go4system, rootsystem,
00725                     path, ldpath, remotedir, remotecommand, name, serverhost, negport);
00726             }
00727 
00728              rev=gSystem->Exec(commandstring);
00729     }
00730   // cout << commandstring << remotehost << "display" << serverdisplay << endl;
00731 //
00732    //cout << "######## returned from gSystem->Exec() with value "<<rev<<endl;
00733    StartConnectorThread();
00734    return rev;
00735 }
00736 
00737 
00738 ClassImp(TGo4ServerTask)
00739 
00740 
00741 
00742 
00743 //----------------------------END OF GO4 SOURCE FILE ---------------------

Generated on Tue Nov 8 10:56:06 2005 for Go4-v2.10-5 by doxygen1.2.15