Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

TGo4CommandRunnable.cxx

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

Generated on Fri Nov 28 12:59:29 2008 for Go4-v3.04-1 by  doxygen 1.4.2