YARP
Yet Another Robot Platform
RunProcManager.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * Copyright (C) 2006-2010 RobotCub Consortium
4  * All rights reserved.
5  *
6  * This software may be modified and distributed under the terms of the
7  * BSD-3-Clause license. See the accompanying LICENSE file for details.
8  */
9 
10 #ifndef YARP_RUN_IMPL_RUNPROCMANAGER_H
11 #define YARP_RUN_IMPL_RUNPROCMANAGER_H
12 
13 #if defined(_WIN32)
14 # if !defined(WIN32_LEAN_AND_MEAN)
15 # define WIN32_LEAN_AND_MEAN
16 # endif
17 # include <windows.h>
18 #else
19 # include <sys/types.h>
20 # include <cerrno>
21 # include <cstdlib>
22 # include <fcntl.h>
25 #endif
26 
27 #include <cstdio>
28 #include <yarp/run/Run.h>
29 #include <yarp/os/Bottle.h>
30 #include <mutex>
31 #include <string>
33 
34 
35 #if defined(_WIN32)
36 typedef DWORD PID;
37 typedef HANDLE FDESC;
38 #else
39 #include <yarp/os/Thread.h>
40 typedef pid_t PID;
41 typedef int FDESC;
42 typedef void* HANDLE;
43 
44 int CLOSE(int h);
45 int SIGNAL(int pid, int signum);
46 
48 {
49 public:
51  {
52  int warn_suppress = yarp::run::impl::pipe(pipe_sync);
53  YARP_UNUSED(warn_suppress);
54  }
55  virtual ~ZombieHunterThread(){}
56 
57  void onStop() override
58  {
59  close(pipe_sync[0]);
60  close(pipe_sync[1]);
61  }
62 
63  void run() override
64  {
65  char dummy[8];
66 
67  while (!isStopping())
68  {
69 
70  if (read(pipe_sync[0], dummy, sizeof(char) * 8) <= 0) {
71  //If EOF or error
72  break;
73  }
74  //else if I'm here it means a child has terminated
75  //If I call wait I can find the exit status of the child process
76 
77  while (true)
78  {
79  //check exit status of the child
80  PID zombie = yarp::os::impl::wait(nullptr);
81  //PID can be:
82  // - Child stopped or terminated => PID of child
83  // - Error => -1
84 
85  //PID zombie=waitpid(-1, nullptr, WNOHANG);
86 
87  if (zombie > 0)
88  {
89  //Remove child information from the process info table
90  yarp::run::Run::CleanZombie(zombie);
91  }
92  else
93  {
94  break;
95  }
96  }
97  }
98  }
99 
101  {
102  ssize_t warn_suppress = write(pipe_sync[1], "zombie", sizeof(char) * (strlen("zombie") + 1));
103  YARP_UNUSED(warn_suppress);
104  }
105 
106 protected:
107  int pipe_sync[2];
108 };
109 
110 #endif
111 
112 
113 #define YARPRUN_ERROR -1
114 
116 {
117 public:
118  YarpRunProcInfo(std::string& alias, std::string& on, PID pidCmd, HANDLE handleCmd, bool hold);
120  {
121 
122  }
123  bool Match(std::string& alias){ return mAlias==alias; }
124 #if !defined(_WIN32)
125  virtual bool Clean(PID pid, YarpRunProcInfo* &pRef)
126  {
127  if (mPidCmd==pid)
128  {
129  mPidCmd=0;
130  pRef=this;
131  return true;
132  }
133 
134  pRef = nullptr;
135  return false;
136  }
137 #endif
138  virtual bool Signal(int signum);
139 
140  virtual bool Clean();
141 
142  virtual bool IsActive();
143 
144  virtual void finalize(){}
145 
146  void setCmd(const std::string& cmd) { mCmd = cmd; }
147  void setEnv(const std::string& env) { mEnv = env; }
148 
149 protected:
150  std::string mAlias;
151  std::string mOn;
152 
154  bool mCleanCmd;
155 
156  HANDLE mHandleCmd; // only windows
157  bool mHold; // only linux
158 
159  std::string mCmd;
160  std::string mEnv;
161 
162  friend class YarpRunInfoVector;
163 };
164 
166 {
167 public:
170 
171  int Size(){ return m_nProcesses; }
172  bool Add(YarpRunProcInfo *process);
173  int Signal(std::string& alias, int signum);
174  int Killall(int signum);
175 
176 #if defined(_WIN32)
177  HANDLE hZombieHunter;
178  void GetHandles(HANDLE* &lpHandles, DWORD &nCount);
179 #else
180  bool CleanZombie(int zombie);
181 #endif
182 
184  bool IsRunning(std::string &alias);
185 
186  std::mutex mutex;
187 
188 protected:
189  void Pack();
190 
191  static const int MAX_PROCESSES=1024;
195 };
196 
198 {
199 public:
200  YarpRunCmdWithStdioInfo(std::string& alias,
201  std::string& on,
202  std::string& stdio,
203  PID pidCmd,
204  PID pidStdout,
205  FDESC readFromPipeCmdToStdout,
206  FDESC writeToPipeCmdToStdout,
207  HANDLE handleCmd,
208  bool hold);
209 
210  YarpRunCmdWithStdioInfo(std::string& alias,
211  std::string& on,
212  std::string& stdio,
213  PID pidCmd,
214  std::string& stdioUUID,
215  YarpRunInfoVector* stdioVector,
216  PID pidStdin,
217  PID pidStdout,
218  FDESC readFromPipeStdinToCmd,
219  FDESC writeToPipeStdinToCmd,
220  FDESC readFromPipeCmdToStdout,
221  FDESC writeToPipeCmdToStdout,
222  HANDLE handleCmd,
223  bool hold);
224 
226 
227  bool Clean() override;
228 
229  void finalize() override
230  {
231  TerminateStdio();
232  }
233 
234  void TerminateStdio();
235 
236 #if !defined(_WIN32)
237  bool Clean(PID pid, YarpRunProcInfo* &pRef) override
238  {
239  pRef = nullptr;
240 
241  if (mPidCmd==pid)
242  {
243  mPidCmd=0;
244 
245  if (!mKillingStdin && mPidStdin) yarp::os::impl::kill(mPidStdin, SIGTERM);
246  if (!mKillingStdout && mPidStdout) yarp::os::impl::kill(mPidStdout, SIGTERM);
247 
249  }
250  else if (mPidStdin==pid)
251  {
252  mPidStdin=0;
253 
254  if (!mKillingCmd && mPidCmd) yarp::os::impl::kill(mPidCmd, SIGTERM);
255  if (!mKillingStdout && mPidStdout) yarp::os::impl::kill(mPidStdout, SIGTERM);
256 
258  }
259  else if (mPidStdout==pid)
260  {
261  mPidStdout=0;
262 
263  if (!mKillingCmd && mPidCmd) yarp::os::impl::kill(mPidCmd, SIGTERM);
264  if (!mKillingStdin && mPidStdin) yarp::os::impl::kill(mPidStdin, SIGTERM);
265 
267  }
268  else return false;
269 
270  if (!mKillingStdio)
271  {
272  mKillingStdio=true;
273 
278 
283  }
284 
285  if (!mPidCmd && !mPidStdin && !mPidStdout) pRef=this;
286 
287  return true;
288  }
289 #endif
290 protected:
295 
300 
301  std::string mStdio;
302  std::string mStdioUUID;
303 
308 
310 };
311 
312 inline std::string int2String(int x)
313 {
314  char buff[16];
315  sprintf(buff, "%d", x);
316  return std::string(buff);
317 }
318 
319 #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:73
An abstraction for a thread of execution.
Definition: Thread.h:25
bool isStopping()
Returns true if the thread is stopping (Thread::stop has been called).
Definition: Thread.cpp:102
::ssize_t ssize_t
Definition: numeric.h:60
bool read(ImageOf< PixelRgb > &dest, const std::string &src, image_fileformat format=FORMAT_ANY)
Definition: ImageFile.cpp:656
bool write(const ImageOf< PixelRgb > &src, const std::string &dest, image_fileformat format=FORMAT_PPM)
Definition: ImageFile.cpp:804
#define YARP_UNUSED(var)
Definition: api.h:159