GSI Object Oriented Online Offline (Go4)  GO4-5.3.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
TGo4CommandRunnable.cxx
Go to the documentation of this file.
1 // $Id: TGo4CommandRunnable.cxx 1090 2013-12-11 07:11:19Z linev $
2 //-----------------------------------------------------------------------
3 // The GSI Online Offline Object Oriented (Go4) Project
4 // Experiment Data Processing at EE department, GSI
5 //-----------------------------------------------------------------------
6 // Copyright (C) 2000- GSI Helmholtzzentrum f�r Schwerionenforschung GmbH
7 // Planckstr. 1, 64291 Darmstadt, Germany
8 // Contact: http://go4.gsi.de
9 //-----------------------------------------------------------------------
10 // This software can be used under the license agreements as stated
11 // in Go4License.txt file which is part of the distribution.
12 //-----------------------------------------------------------------------
13 
14 #include "TGo4CommandRunnable.h"
15 
16 #include <signal.h>
17 
18 #include "TGo4Log.h"
19 #include "TGo4Thread.h"
20 #include "TGo4BufferQueue.h"
21 #include "TGo4Socket.h"
23 #include "TGo4CommandInvoker.h"
24 #include "TGo4TaskHandler.h"
26 #include "TGo4ClientTask.h"
27 #include "TGo4ComQuit.h"
28 
29 #include <sstream>
30 #include "Riostream.h"
31 
32 
34  TGo4TaskHandler* hand, Bool_t receivermode) :
35  TGo4TaskHandlerRunnable(name,man,hand,receivermode)
36 {
40 }
41 
42 
44 {
45 }
46 
47 Int_t TGo4CommandRunnable::Run(void* ptr)
48 {
49  if(!CheckTransportOpen()) return 0;
50  if(fbReceiverMode)
51  {
52  // wait for something from socket
53  Int_t rev=fxTransport->ReceiveBuffer();
54  if(rev>=0)
55  {
56  TBuffer* buffer=const_cast<TBuffer*> (fxTransport->GetBuffer());
57  Int_t val=0;
58  if(CheckStopBuffer(buffer,&val)) return 0; // stop for disconnect mode
59  if(val>=0)
60  {
61  fxTransport->Send(TGo4TaskHandler::Get_fgcOK()); //acknowledge before execute
62  TGo4Task* cli = dynamic_cast<TGo4Task*>(fxManager);
63  // we have a direct command, execute this here:
64  TGo4ComQuit* qcommand = 0;
66  // test here for different command values
67  switch(comvalue)
68  {
69  case kComQuit:
71  fxManager->SetBeingQuit(kTRUE); // flag for the application that we expect to be quit soon
72  TGo4Log::Debug(" Command runnable executing direct command QUIT... ");
73  //cli->Quit();
74  // note: need execution of quit in local command thread,
75  // because we are inside thread to be cancelled...
76  qcommand = new TGo4ComQuit;
77  cli->SubmitLocalCommand(qcommand);
78  break;
79  case kComKillMain:
81  TGo4Log::Debug(" Command runnable executing direct command KILL MAIN... ");
82  cli->KillMain();
83  break;
84  case kComRestartMain:
86  TGo4Log::Debug(" Command runnable executing direct command RESTART MAIN... ");
87  cli->RestartMain();
88  break;
89  case kComCloseInput:
90  // this case should be treated by CheckStopBuffer, so:
91  TGo4Log::Debug("NEVER COME HERE: Command runnable has direct command CLOSE INPUT");
92  // TGo4Log::Debug(" Command runnable executing direct command CLOSE INPUT... ");
93  // GetThread()->Stop();
94  break;
95  default:
96  TGo4Log::Debug(" Command runnable direct command value %d UNKNOWN! ",
97  comvalue);
98  break;
99 
100 
101  }
102  // end direct command section
103  } // if(val>0)
104  else
105  {
106  fxBufferQueue->AddBuffer(buffer, kTRUE);
108  } // end if((val>0))
109  } // if(rev>=0)
110  else
111  {
113  {
114  // TSocket error because of window resize, do not abort!
115  TGo4Log::Debug(" %s: caught SIGWINCH ", GetName());
117  }
118  else if(fxManager->IsTerminating())
119  {
120  //std::cout <<"Receive error in "<<GetName()<< " while threadmanager is terminating. Ignored!" << std::endl;
121  TGo4Log::Debug("Receive Error in %s during threadmanager termination. Ignored.",GetName());
122  GetThread()->Stop();
123 
124  }
125  else
126  {
127  if(fxTaskHandler->IsClientMode()) RedirectIO(); // only suppress output for analysis clients (correct shutdown if run in QtWindow!)
128  TGo4Log::Debug("Receive Error in %s, aborting taskhandler...",GetName());
129  throw TGo4TaskHandlerAbortException(this);
130  }
131  } // end if (rev>=0)
132  } //end if(fbReceiverMode)
133  else
134  {
135  // get next command from queue or wait for it
136  TBuffer* buf= fxBufferQueue->WaitBuffer();
137  if (buf)
138  // check if there is really an object from queue
139  {
140  Bool_t stopmode=CheckStopBuffer(buf);
141  // send over inter task transport
142  fxTransport->SendBuffer(buf);
143  // std::cout << "command runnable: sending buffer via transport" << std::endl;
145  if(stopmode) return 0; // no handshake after stop buffer
146  char* revchar=fxTransport->RecvRaw("dummy"); // wait for o.k. string
147  if(revchar==0)
148  {
149  // error, received garbage
151  //if (TGo4SocketSignalHandler::fgxLastSignal == kSigWindowChanged)
152  {
153  // TSocket error because of window resize, do not abort!
154  TGo4Log::Debug(" %s: caught SIGWINCH ",GetName());
156  //TGo4SocketSignalHandler::fgxLastSignal = (ESignals) 0;
157  }
158  else
159  {
160  //RedirectIO(); // do not redirect output for command sender, will not terminate!
161  TGo4Log::Debug(" !!!Connection Error -1 in CommandRunnable ''%s''!!!",GetName());
162  throw TGo4TaskHandlerAbortException(this);
163  }
164  }
165  else
166  {
167  // we received something, proceed
168  } // end if(revchar==0)
169 
170  if(!strcmp(revchar,TGo4TaskHandler::Get_fgcOK()) )
171  {
172  // fine, command has reached its destination, anyhow..
173  }
174  else if(!strcmp(revchar,TGo4TaskHandler::Get_fgcERROR()))
175  {
176  // client signals any kind of error with last command
177  TGo4Log::Debug(" CommandRunnable ''%s'' received command error string!!!",GetName());
178  }
179  else
180  {
181  // error, received something else
182  TGo4Log::Debug(" !!!Connection Error -3 in CommandRunnable ''%s''!!!",GetName());
183  //throw TGo4TerminateException(this);
184  }
185  }
186  else
187  {
188  if(!GetThread()->IsRunning())
189  {
190  // when gui client is disconnected by slave server itself
191  // (server shutdown from other gui), we have to react on Queue wakeup
192  // in command queue from the TGo4TaskHandler::StopTransportThreads
193  //std::cout <<"Command runnable gets null from queue and is stopped!!!!" << std::endl;
194  return 0;
195  }
196  // do nothing, return for next wait
197  }
198  } // end else if(fbReceiverMode)
199  return 0;
200 }
201 
202 
204 {
205  // note: this method is only called in case of aborting,
206  // so we do not care about our memory leak...JA
207  std::ostringstream* strout = new std::ostringstream;
208  //std::streambuf* ccc_buffer = std::cout.rdbuf(); // would need it to recover std::cout
209  std::cout.rdbuf(strout->rdbuf());
210  std::ostringstream* strerr = new std::ostringstream;
211  //std::streambuf* std::cerr_buffer = std::cerr.rdbuf(); // would need to recover std::cerr later
212  std::cerr.rdbuf(strerr->rdbuf());
213 }
TGo4Socket * GetCommandTransport() const
Go4EmergencyCommand_t
Bool_t SubmitLocalCommand(TGo4Command *com)
Definition: TGo4Task.cxx:546
TGo4ThreadManager * fxManager
Definition: TGo4Runnable.h:71
const TBuffer * GetBuffer() const
Definition: TGo4Socket.h:58
virtual Int_t Send(TObject *obj)
Definition: TGo4Socket.cxx:352
Int_t SendBuffer(TBuffer *buf)
Definition: TGo4Socket.cxx:236
virtual Int_t Run(void *ptr)
Bool_t Stop()
Definition: TGo4Thread.cxx:328
TGo4Thread * GetThread() const
Definition: TGo4Runnable.h:45
static const char * Get_fgcERROR()
static const char * Get_fgcOK()
Bool_t IsClientMode() const
virtual void RestartMain()
Definition: TGo4Task.cxx:125
static void SetLastSignal(Int_t v=0)
TGo4Queue * GetCommandQueue() const
TBuffer * WaitBuffer()
Int_t ReceiveBuffer()
Definition: TGo4Socket.cxx:289
static TGo4CommandInvoker * Instance()
TGo4CommandInvoker * fxInvoker
void AddBuffer(TBuffer *buffer, Bool_t clone=kFALSE)
Bool_t CheckStopBuffer(TBuffer *buf, Int_t *result=0)
Go4CommandMode_t GetRole()
virtual void KillMain()
Definition: TGo4Task.cxx:120
void SetBeingQuit(Bool_t on)
Bool_t IsTerminating() const
virtual char * RecvRaw(const char *name=0)
Definition: TGo4Socket.cxx:421
void FreeBuffer(TBuffer *buffer)
static void Debug(const char *text,...)
Definition: TGo4Log.cxx:270