GSI Object Oriented Online Offline (Go4) GO4-6.4.0
Loading...
Searching...
No Matches
TGo4CommandRunnable.cxx
Go to the documentation of this file.
1// $Id$
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 fuer 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 <sstream>
17#include <iostream>
18
19#include "TGo4Log.h"
20#include "TGo4Thread.h"
21#include "TGo4BufferQueue.h"
22#include "TGo4Socket.h"
24#include "TGo4CommandInvoker.h"
25#include "TGo4TaskHandler.h"
27#include "TGo4ClientTask.h"
28#include "TGo4ComQuit.h"
29
30
32 TGo4TaskHandler *hand, Bool_t receivermode) :
33 TGo4TaskHandlerRunnable(name,man,hand,receivermode)
34{
35 fxBufferQueue = dynamic_cast<TGo4BufferQueue*> (fxTaskHandler->GetCommandQueue() );
36 fxTransport = fxTaskHandler->GetCommandTransport();
38}
39
40
44
46{
47 if(!CheckTransportOpen()) return 0;
49 {
50 // wait for something from socket
51 Int_t rev=fxTransport->ReceiveBuffer();
52 if(rev >= 0)
53 {
54 TBuffer *buffer = const_cast<TBuffer *> (fxTransport->GetBuffer());
55 Int_t val = 0;
56 if(CheckStopBuffer(buffer,&val)) return 0; // stop for disconnect mode
57 if(val >= 0)
58 {
59 fxTransport->Send(TGo4TaskHandler::Get_fgcOK()); //acknowledge before execute
60 TGo4Task* cli = dynamic_cast<TGo4Task*>(fxManager);
61 // we have a direct command, execute this here:
62 TGo4ComQuit* qcommand = nullptr;
64 // test here for different command values
65 switch(comvalue)
66 {
67 case kComQuit:
68 if(fxTaskHandler->GetRole()==kGo4ComModeObserver) break;
69 fxManager->SetBeingQuit(kTRUE); // flag for the application that we expect to be quit soon
70 TGo4Log::Debug(" Command runnable executing direct command QUIT... ");
71 //cli->Quit();
72 // note: need execution of quit in local command thread,
73 // because we are inside thread to be cancelled...
74 qcommand = new TGo4ComQuit;
75 cli->SubmitLocalCommand(qcommand);
76 break;
77 case kComKillMain:
78 if(fxTaskHandler->GetRole()==kGo4ComModeObserver) break;
79 TGo4Log::Debug(" Command runnable executing direct command KILL MAIN... ");
80 cli->KillMain();
81 break;
82 case kComRestartMain:
83 if(fxTaskHandler->GetRole()==kGo4ComModeObserver) break;
84 TGo4Log::Debug(" Command runnable executing direct command RESTART MAIN... ");
85 cli->RestartMain();
86 break;
87 case kComCloseInput:
88 // this case should be treated by CheckStopBuffer, so:
89 TGo4Log::Debug("NEVER COME HERE: Command runnable has direct command CLOSE INPUT");
90 // TGo4Log::Debug(" Command runnable executing direct command CLOSE INPUT... ");
91 // GetThread()->Stop();
92 break;
93 case kComAbortTask:
94 TGo4Log::Debug("Command runnable kComAbortTask");
95 break;
96 default:
97 TGo4Log::Debug(" Command runnable direct command value %d UNKNOWN!", comvalue);
98 break;
99
100 }
101 // end direct command section
102 } // if(val>0)
103 else
104 {
105 fxBufferQueue->AddBuffer(buffer, kTRUE);
107 } // end if((val>0))
108 } // if(rev >= 0)
109 else
110 {
112 {
113 // TSocket error because of window resize, do not abort!
114 TGo4Log::Debug(" %s: caught SIGWINCH ", GetName());
116 }
117 else if(fxManager->IsTerminating())
118 {
119 TGo4Log::Debug("Receive Error in %s during threadmanager termination. Ignored.",GetName());
120 GetThread()->Stop();
121 }
122 else
123 {
124 if(fxTaskHandler->IsClientMode()) RedirectIO(); // only suppress output for analysis clients (correct shutdown if run in QtWindow!)
125 TGo4Log::Debug("Receive Error in %s, aborting taskhandler...",GetName());
127 }
128 } // end if (rev >= 0)
129 } //end if(fbReceiverMode)
130 else
131 {
132 // get next command from queue or wait for it
133 TBuffer *buf= fxBufferQueue->WaitBuffer();
134 if (buf)
135 // check if there is really an object from queue
136 {
137 Bool_t stopmode=CheckStopBuffer(buf);
138 // send over inter task transport
139 fxTransport->SendBuffer(buf);
140 fxBufferQueue->FreeBuffer(buf);
141 if(stopmode) return 0; // no handshake after stop buffer
142 char *revchar = fxTransport->RecvRaw("dummy"); // wait for o.k. string
143 if(!revchar)
144 {
145 // error, received garbage
147 //if (TGo4SocketSignalHandler::fgxLastSignal == kSigWindowChanged)
148 {
149 // TSocket error because of window resize, do not abort!
150 TGo4Log::Debug(" %s: caught SIGWINCH ",GetName());
152 //TGo4SocketSignalHandler::fgxLastSignal = (ESignals) 0;
153 }
154 else
155 {
156 //RedirectIO(); // do not redirect output for command sender, will not terminate!
157 TGo4Log::Debug(" !!!Connection Error -1 in CommandRunnable ''%s''!!!",GetName());
159 }
160 }
161 else
162 {
163 // we received something, proceed
164 }
165
166 if(!strcmp(revchar,TGo4TaskHandler::Get_fgcOK()) )
167 {
168 // fine, command has reached its destination, anyhow..
169 }
170 else if(!strcmp(revchar,TGo4TaskHandler::Get_fgcERROR()))
171 // client signals any kind of error with last command
172 {
173 // client signals any kind of error == 0 with last command
174 TGo4Log::Debug(" CommandRunnable ''%s'' received command error string!!!",GetName());
175 }
176 else
177 {
178 // error, received something else
179 TGo4Log::Debug(" !!!Connection Error -3 in CommandRunnable ''%s''!!!",GetName());
180 //throw TGo4TerminateException(this);
181 }
182 }
183 else
184 {
185 if(!GetThread()->IsRunning())
186 {
187 // when gui client is disconnected by slave server itself
188 // (server shutdown from other gui), we have to react on Queue wakeup
189 // in command queue from the TGo4TaskHandler::StopTransportThreads
190 return 0;
191 }
192 // do nothing, return for next wait
193 }
194 } // end else if(fbReceiverMode)
195 return 0;
196}
197
198
200{
201 // note: this method is only called in case of aborting,
202 // so we do not care about our memory leak...JA
203 std::ostringstream* strout = new std::ostringstream;
204 //std::streambuf* ccc_buffer = std::cout.rdbuf(); // would need it to recover std::cout
205 std::cout.rdbuf(strout->rdbuf());
206 std::ostringstream* strerr = new std::ostringstream;
207 //std::streambuf* std::cerr_buffer = std::cerr.rdbuf(); // would need to recover std::cerr later
208 std::cerr.rdbuf(strerr->rdbuf());
209}
Go4EmergencyCommand_t
@ kComAbortTask
@ kComRestartMain
@ kComKillMain
@ kComCloseInput
@ kGo4ComModeObserver
Definition TGo4Command.h:29
Class containing a pointer queue for TBuffers.
Command to quit (terminate) the client, after successful quit, the client may be removed from taskman...
Definition TGo4ComQuit.h:23
static TGo4CommandInvoker * Instance()
Int_t Run(void *ptr) override
The working function which runs in the thread.
void RedirectIO()
for error in socket: redirect std::cout/std::cerr to dummy buffer to avoid trouble if client is runni...
TGo4CommandInvoker * fxInvoker
client mode: link to external (static) invoker singleton, that is used to execute the async commands ...
static void Debug(const char *text,...) GO4_PRINTF_ARGS
User shortcut for message with prio 0.
Definition TGo4Log.cxx:281
TGo4Thread * GetThread() const
TGo4ThreadManager * fxManager
The threadmanager which is responsible for our thread.
static void SetLastSignal(Int_t v=0)
Bool_t fbReceiverMode
flag indicating operation mode of runnable, depending on client or server mode of task handler
Bool_t CheckTransportOpen()
Test if socket transport exists and is open.
Bool_t CheckStopBuffer(TBuffer *buf, Int_t *result=nullptr)
Test if buffer contains a message to stop this runnable.
TGo4TaskHandler * fxTaskHandler
link to external task handler (for server mode) 1 1
TGo4Socket * fxTransport
link to external inter-tasl transport channel
TGo4TaskHandlerRunnable(const char *name, TGo4ThreadManager *man, TGo4TaskHandler *hand, Bool_t receivermode=kTRUE)
TGo4BufferQueue * fxBufferQueue
Link to external buffer queue.
This class is responsible for the interconnection of two tasks: provided are three communication chan...
static const char * Get_fgcERROR()
static const char * Get_fgcOK()
Go4 Task.
Definition TGo4Task.h:39
Bool_t SubmitLocalCommand(TGo4Command *com)
Send given command to the current client task.
Definition TGo4Task.cxx:508
virtual void RestartMain()
Restart the main thread; method to be called from command, should be overridden in user implementatio...
Definition TGo4Task.cxx:125
virtual void KillMain()
Kill the main thread; method to be called from command, should be overridden in user implementation.
Definition TGo4Task.cxx:120
Go4 thread manager.
Bool_t Stop()
resets running flag for runnable