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

/Go4TaskHandler/TGo4CommandRunnable.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 "TGo4CommandRunnable.h"
00017 
00018 #include <iostream.h>
00019 
00020 #include "Go4Log/TGo4Log.h"
00021 #include "Go4ThreadManager/TGo4ThreadManager.h"
00022 #include "Go4CommandsTaskHandler/Go4CommandsTaskHandler.h"
00023 #include "Go4Queue/TGo4BufferQueue.h"
00024 #include "Go4Socket/TGo4Socket.h"
00025 #include "Go4Socket/TGo4SocketSignalHandler.h"
00026 #include "Go4CommandsBase/TGo4CommandInvoker.h"
00027 #include "Go4CommandsBase/TGo4Command.h"
00028 #include "TGo4TaskHandler.h"
00029 #include "TGo4TaskHandlerAbortException.h"
00030 #include "TGo4ClientTask.h"
00031 #include <iostream>
00032 #include <sstream>
00033 
00034 using namespace std;
00035 
00036 TGo4CommandRunnable::TGo4CommandRunnable(const char* name,
00037                                          TGo4ThreadManager* man,
00038                                          TGo4TaskHandler* hand,
00039                                          Bool_t receivermode)
00040    :TGo4TaskHandlerRunnable(name,man,hand,receivermode)
00041 {
00042    fxBufferQueue=dynamic_cast<TGo4BufferQueue*> (fxTaskHandler->GetCommandQueue() );
00043    fxTransport=fxTaskHandler->GetCommandTransport();
00044    fxInvoker=TGo4CommandInvoker::Instance();
00045 }
00046 
00047 
00048 TGo4CommandRunnable::~TGo4CommandRunnable()
00049 {
00050 }
00051 
00052 Int_t TGo4CommandRunnable::Run(void* ptr)
00053 {
00054    if(!CheckTransportOpen()) return 0;
00055    if(fbReceiverMode)
00056       {
00057       // wait for something from socket
00058       Int_t rev=fxTransport->ReceiveBuffer();
00059       if(rev>=0)
00060          {
00061           TBuffer* buffer=const_cast<TBuffer*> (fxTransport->GetBuffer());
00062           Int_t val=0;
00063           if(CheckStopBuffer(buffer,&val)) return 0; // stop for disconnect mode
00064           if(val>=0)
00065              {
00066              fxTransport->Send(TGo4TaskHandler::fgcOK); //acknowledge before execute
00067              TGo4Task* cli = dynamic_cast<TGo4Task*>(fxManager);
00068                // we have a direct command, execute this here:
00069              TGo4ComQuit* qcommand=0;
00070              Go4EmergencyCommand_t comvalue= (Go4EmergencyCommand_t) (val);
00071              // test here for different command values
00072              switch(comvalue)
00073                 {
00074                 case kComQuit:
00075                    if(fxTaskHandler->GetRole()==kGo4ComModeObserver) break;
00076                    TGo4Log::Debug(" Command runnable executing direct command QUIT... ");
00077                    //cli->Quit();
00078                    // note: need execution of quit in local command thread,
00079                    // because we are inside thread to be cancelled...                     
00080                    qcommand = new TGo4ComQuit;
00081                    cli->SubmitLocalCommand(qcommand);                
00082                    break;
00083                 case kComKillMain:
00084                    if(fxTaskHandler->GetRole()==kGo4ComModeObserver) break;
00085                    TGo4Log::Debug(" Command runnable executing direct command KILL MAIN... ");
00086                    cli->KillMain();
00087                    break;
00088                 case kComRestartMain:
00089                    if(fxTaskHandler->GetRole()==kGo4ComModeObserver) break;
00090                    TGo4Log::Debug(" Command runnable executing direct command RESTART MAIN... ");
00091                    cli->RestartMain();
00092                    break;
00093                 case kComCloseInput:
00094                      // this case should be treated by CheckStopBuffer, so:
00095                      TGo4Log::Debug("NEVER COME HERE: Command runnable has direct command CLOSE INPUT");
00096    //                TGo4Log::Debug(" Command runnable executing direct command CLOSE INPUT... ");
00097    //                GetThread()->Stop();
00098                    break;
00099                 default:
00100                    TGo4Log::Debug(" Command runnable direct command value %d UNKNOWN! ",
00101                             comvalue);
00102                    break;
00103    
00104    
00105                 }
00106             // end direct command section
00107              } // if(val>0)
00108       else
00109          {
00110          fxBufferQueue->AddBuffer(buffer, kTRUE);
00111          fxTransport->Send(TGo4TaskHandler::fgcOK);
00112          }  // end if((val>0))
00113       } // if(rev>=0)
00114    else
00115       {
00116          if (TGo4SocketSignalHandler::fgiLastSignal == SIGWINCH)
00117             {
00118                // TSocket error because of window resize, do not abort!
00119                TGo4Log::Debug(" %s: caught SIGWINCH ", GetName());
00120                TGo4SocketSignalHandler::fgiLastSignal = 0; // reset
00121             }
00122          else if(fxManager->IsTerminating())
00123             {
00124                //cout <<"Receive error in "<<GetName()<< " while threadmanager is terminating. Ignored!" << endl;
00125                TGo4Log::Debug("Receive Error in %s during threadmanager termination. Ignored.",GetName());
00126                GetThread()->Stop();
00127                
00128             }   
00129          else
00130             {
00131                if(fxTaskHandler->IsClientMode()) RedirectIO(); // only suppress output for analysis clients (correct shutdown if run in QtWindow!)
00132                TGo4Log::Debug("Receive Error in CommandRunnable, terminating...");
00133                throw TGo4TaskHandlerAbortException(this);
00134             }         // if (TGo4SocketSignalHandler::fgiLastSignal == SIGWINCH)
00135        } // end if (rev>=0)
00136    }  //end if(fbReceiverMode)
00137    else
00138       {
00139          // get next command from queue or wait for it
00140         TBuffer* buf= fxBufferQueue->WaitBuffer();
00141             if (buf)
00142                // check if there is really an object from queue
00143                {
00144                     Bool_t stopmode=CheckStopBuffer(buf); 
00145                      // send over inter task transport
00146                      fxTransport->SendBuffer(buf);
00147    //                  cout << "command runnable: sending buffer via transport" << endl;
00148                      fxBufferQueue->FreeBuffer(buf);
00149                      if(stopmode) return 0; // no handshake after stop buffer
00150                      Text_t* revchar=fxTransport->RecvRaw("dummy"); // wait for o.k. string
00151                      if(revchar==0)
00152                         {
00153                            // error, received garbage
00154                             if (TGo4SocketSignalHandler::fgiLastSignal == SIGWINCH)
00155                             //if (TGo4SocketSignalHandler::fgxLastSignal == kSigWindowChanged)
00156                               {
00157                                  // TSocket error because of window resize, do not abort!
00158                                  TGo4Log::Debug(" %s: caught SIGWINCH ",GetName());
00159                                  TGo4SocketSignalHandler::fgiLastSignal = 0; // reset
00160                                  //TGo4SocketSignalHandler::fgxLastSignal = (ESignals) 0;
00161                               }
00162                            else
00163                               {
00164                                  //RedirectIO(); // do not redirect output for command sender, will not terminate!
00165                                  TGo4Log::Debug(" !!!Connection Error -1 in CommandRunnable ''%s''!!!",GetName());
00166                                  throw TGo4TaskHandlerAbortException(this);
00167                               } // end if (TGo4SocketSignalHandler::fgiLastSignal == SIGWINCH)
00168                         }
00169                      else
00170                         {
00171                             // we received something, proceed
00172                         } // end if(revchar==0)
00173    
00174                      if(!strcmp(revchar,TGo4TaskHandler::fgcOK) )
00175                         {
00176                            // fine, command has reached its destination, anyhow..
00177                         }
00178                      else if(!strcmp(revchar,TGo4TaskHandler::fgcERROR))
00179                         {
00180                            // client signals any kind of error with last command
00181                            TGo4Log::Debug(" CommandRunnable ''%s'' received command error string!!!",GetName());
00182                         }
00183                      else
00184                         {
00185                            // error, received something else
00186                            TGo4Log::Debug(" !!!Connection Error -3 in CommandRunnable ''%s''!!!",GetName());
00187                            //throw TGo4TerminateException(this);
00188                         }
00189                }
00190             else
00191                {
00192                   if(!GetThread()->IsRunning())
00193                         {
00194                            // when gui client is disconnected by slave server itself
00195                            // (server shutdown from other gui), we have to react on Queue wakeup 
00196                            // in command queue from the TGo4TaskHandler::StopTransportThreads
00197                            //cout <<"Command runnable gets null from queue and is stopped!!!!" << endl;
00198                            return 0; 
00199                         }
00200                   // do nothing, return for next wait
00201                }
00202      }   // end else if(fbReceiverMode)
00203    return 0;
00204 }
00205 
00206 
00207 void TGo4CommandRunnable::RedirectIO()
00208 {
00209 // note: this method is only called in case of aborting,
00210 // so we do not care about our memory leak...JA
00211 ostringstream* strout = new ostringstream;
00212 //streambuf* cout_buffer = cout.rdbuf(); // would need it to recover cout   
00213 cout.rdbuf(strout->rdbuf());
00214 ostringstream* strerr = new ostringstream;
00215 //streambuf* cerr_buffer = cerr.rdbuf(); // would need to rcover cerr later   
00216 cerr.rdbuf(strerr->rdbuf());    
00217 }
00218 
00219 //----------------------------END OF GO4 SOURCE FILE ---------------------

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