YARP
Yet Another Robot Platform
RunProcManager.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3  * SPDX-FileCopyrightText: 2006-2010 RobotCub Consortium
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef YARP_RUN_IMPL_RUNPROCMANAGER_H
8 #define YARP_RUN_IMPL_RUNPROCMANAGER_H
9 
10 #if defined(_WIN32)
11 # if !defined(WIN32_LEAN_AND_MEAN)
12 # define WIN32_LEAN_AND_MEAN
13 # endif
14 # include <windows.h>
15 #else
16 # include <sys/types.h>
17 # include <cerrno>
18 # include <cstdlib>
19 # include <fcntl.h>
22 #endif
23 
24 #include <cstdio>
25 #include <yarp/run/Run.h>
26 #include <yarp/os/Bottle.h>
27 #include <mutex>
28 #include <string>
30 
31 
32 #if defined(_WIN32)
33 typedef DWORD PID;
34 typedef HANDLE FDESC;
35 #else
36 #include <yarp/os/Thread.h>
37 typedef pid_t PID;
38 typedef int FDESC;
39 typedef void* HANDLE;
40 
41 int CLOSE(int h);
42 int SIGNAL(int pid, int signum);
43 
45 {
46 public:
48  {
49  int warn_suppress = yarp::run::impl::pipe(pipe_sync);
50  YARP_UNUSED(warn_suppress);
51  }
52  virtual ~ZombieHunterThread(){}
53 
54  void onStop() override
55  {
56  close(pipe_sync[0]);
57  close(pipe_sync[1]);
58  }
59 
60  void run() override
61  {
62  char dummy[8];
63 
64  while (!isStopping())
65  {
66 
67  if (read(pipe_sync[0], dummy, sizeof(char) * 8) <= 0) {
68  //If EOF or error
69  break;
70  }
71  //else if I'm here it means a child has terminated
72  //If I call wait I can find the exit status of the child process
73 
74  while (true)
75  {
76  //check exit status of the child
77  PID zombie = yarp::os::impl::wait(nullptr);
78  //PID can be:
79  // - Child stopped or terminated => PID of child
80  // - Error => -1
81 
82  //PID zombie=waitpid(-1, nullptr, WNOHANG);
83 
84  if (zombie > 0)
85  {
86  //Remove child information from the process info table
87  yarp::run::Run::CleanZombie(zombie);
88  }
89  else
90  {
91  break;
92  }
93  }
94  }
95  }
96 
98  {
99  ssize_t warn_suppress = write(pipe_sync[1], "zombie", sizeof(char) * (strlen("zombie") + 1));
100  YARP_UNUSED(warn_suppress);
101  }
102 
103 protected:
104  int pipe_sync[2];
105 };
106 
107 #endif
108 
109 
110 #define YARPRUN_ERROR -1
111 
113 {
114 public:
115  YarpRunProcInfo(std::string& alias, std::string& on, PID pidCmd, HANDLE handleCmd, bool hold);
117  {
118 
119  }
120  bool Match(std::string& alias){ return mAlias==alias; }
121 #if !defined(_WIN32)
122  virtual bool Clean(PID pid, YarpRunProcInfo* &pRef)
123  {
124  if (mPidCmd==pid)
125  {
126  mPidCmd=0;
127  pRef=this;
128  return true;
129  }
130 
131  pRef = nullptr;
132  return false;
133  }
134 #endif
135  virtual bool Signal(int signum);
136 
137  virtual bool Clean();
138 
139  virtual bool IsActive();
140 
141  virtual void finalize(){}
142 
143  void setCmd(const std::string& cmd) { mCmd = cmd; }
144  void setEnv(const std::string& env) { mEnv = env; }
145 
146 protected:
147  std::string mAlias;
148  std::string mOn;
149 
151  bool mCleanCmd;
152 
153  HANDLE mHandleCmd; // only windows
154  bool mHold; // only linux
155 
156  std::string mCmd;
157  std::string mEnv;
158 
159  friend class YarpRunInfoVector;
160 };
161 
163 {
164 public:
167 
168  int Size(){ return m_nProcesses; }
169  bool Add(YarpRunProcInfo *process);
170  int Signal(std::string& alias, int signum);
171  int Killall(int signum);
172 
173 #if defined(_WIN32)
174  HANDLE hZombieHunter;
175  void GetHandles(HANDLE* &lpHandles, DWORD &nCount);
176 #else
177  bool CleanZombie(int zombie);
178 #endif
179 
181  bool IsRunning(std::string &alias);
182 
183  std::mutex mutex;
184 
185 protected:
186  void Pack();
187 
188  static const int MAX_PROCESSES=1024;
192 };
193 
195 {
196 public:
197  YarpRunCmdWithStdioInfo(std::string& alias,
198  std::string& on,
199  std::string& stdio,
200  PID pidCmd,
201  PID pidStdout,
202  FDESC readFromPipeCmdToStdout,
203  FDESC writeToPipeCmdToStdout,
204  HANDLE handleCmd,
205  bool hold);
206 
207  YarpRunCmdWithStdioInfo(std::string& alias,
208  std::string& on,
209  std::string& stdio,
210  PID pidCmd,
211  std::string& stdioUUID,
212  YarpRunInfoVector* stdioVector,
213  PID pidStdin,
214  PID pidStdout,
215  FDESC readFromPipeStdinToCmd,
216  FDESC writeToPipeStdinToCmd,
217  FDESC readFromPipeCmdToStdout,
218  FDESC writeToPipeCmdToStdout,
219  HANDLE handleCmd,
220  bool hold);
221 
223 
224  bool Clean() override;
225 
226  void finalize() override
227  {
228  TerminateStdio();
229  }
230 
231  void TerminateStdio();
232 
233 #if !defined(_WIN32)
234  bool Clean(PID pid, YarpRunProcInfo* &pRef) override
235  {
236  pRef = nullptr;
237 
238  if (mPidCmd==pid)
239  {
240  mPidCmd=0;
241 
242  if (!mKillingStdin && mPidStdin) {
243  yarp::os::impl::kill(mPidStdin, SIGTERM);
244  }
245  if (!mKillingStdout && mPidStdout) {
246  yarp::os::impl::kill(mPidStdout, SIGTERM);
247  }
248 
250  }
251  else if (mPidStdin==pid)
252  {
253  mPidStdin=0;
254 
255  if (!mKillingCmd && mPidCmd) {
256  yarp::os::impl::kill(mPidCmd, SIGTERM);
257  }
258  if (!mKillingStdout && mPidStdout) {
259  yarp::os::impl::kill(mPidStdout, SIGTERM);
260  }
261 
263  }
264  else if (mPidStdout==pid)
265  {
266  mPidStdout=0;
267 
268  if (!mKillingCmd && mPidCmd) {
269  yarp::os::impl::kill(mPidCmd, SIGTERM);
270  }
271  if (!mKillingStdin && mPidStdin) {
272  yarp::os::impl::kill(mPidStdin, SIGTERM);
273  }
274 
276  } else {
277  return false;
278  }
279 
280  if (!mKillingStdio)
281  {
282  mKillingStdio=true;
283 
286  }
289  }
292  }
295  }
296 
301  }
302 
303  if (!mPidCmd && !mPidStdin && !mPidStdout) {
304  pRef = this;
305  }
306 
307  return true;
308  }
309 #endif
310 protected:
315 
320 
321  std::string mStdio;
322  std::string mStdioUUID;
323 
328 
330 };
331 
332 inline std::string int2String(int x)
333 {
334  char buff[16];
335  sprintf(buff, "%d", x);
336  return std::string(buff);
337 }
338 
339 #endif // YARP_RUN_IMPL_RUNPROCMANAGER_H
int SIGNAL(int pid, int signum)
int CLOSE(int h)
int FDESC
void * HANDLE
std::string int2String(int x)
pid_t PID
YarpRunInfoVector * mStdioVector
virtual ~YarpRunCmdWithStdioInfo()
YarpRunCmdWithStdioInfo(std::string &alias, std::string &on, std::string &stdio, PID pidCmd, PID pidStdout, FDESC readFromPipeCmdToStdout, FDESC writeToPipeCmdToStdout, HANDLE handleCmd, bool hold)
bool Clean(PID pid, YarpRunProcInfo *&pRef) override
void finalize() override
int Signal(std::string &alias, int signum)
bool CleanZombie(int zombie)
static const int MAX_PROCESSES
int Killall(int signum)
yarp::os::Bottle PS()
YarpRunInfoVector * m_pStdioMate
YarpRunProcInfo * m_apList[MAX_PROCESSES]
bool IsRunning(std::string &alias)
bool Add(YarpRunProcInfo *process)
bool Match(std::string &alias)
virtual void finalize()
virtual ~YarpRunProcInfo()
std::string mAlias
std::string mOn
void setEnv(const std::string &env)
YarpRunProcInfo(std::string &alias, std::string &on, PID pidCmd, HANDLE handleCmd, bool hold)
virtual bool Signal(int signum)
virtual bool Clean()
virtual bool Clean(PID pid, YarpRunProcInfo *&pRef)
virtual bool IsActive()
void setCmd(const std::string &cmd)
std::string mEnv
std::string mCmd
void run() override
Main body of the new thread.
void onStop() override
Call-back, called while halting the thread (before join).
virtual ~ZombieHunterThread()
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:74
An abstraction for a thread of execution.
Definition: Thread.h:22
bool isStopping()
Returns true if the thread is stopping (Thread::stop has been called).
Definition: Thread.cpp:99
::ssize_t ssize_t
Definition: numeric.h:86
bool read(ImageOf< PixelRgb > &dest, const std::string &src, image_fileformat format=FORMAT_ANY)
Definition: ImageFile.cpp:922
bool write(const ImageOf< PixelRgb > &src, const std::string &dest, image_fileformat format=FORMAT_PPM)
Definition: ImageFile.cpp:1098
#define YARP_UNUSED(var)
Definition: api.h:162