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
YarpRunInfoVector::YarpRunInfoVector
YarpRunInfoVector()
Definition: RunProcManager.cpp:159
YarpRunInfoVector::PS
yarp::os::Bottle PS()
Definition: RunProcManager.cpp:348
yarp::os::Bottle
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:73
YarpRunProcInfo::mAlias
std::string mAlias
Definition: RunProcManager.h:150
YarpRunCmdWithStdioInfo::mCleanStdin
bool mCleanStdin
Definition: RunProcManager.h:293
PlatformSysWait.h
YarpRunProcInfo::finalize
virtual void finalize()
Definition: RunProcManager.h:144
YarpRunInfoVector::m_apList
YarpRunProcInfo * m_apList[MAX_PROCESSES]
Definition: RunProcManager.h:193
yarp::sig::file::read
bool read(ImageOf< PixelRgb > &dest, const std::string &src, image_fileformat format=FORMAT_ANY)
Definition: ImageFile.cpp:827
int2String
std::string int2String(int x)
Definition: RunProcManager.h:312
YarpRunInfoVector::Signal
int Signal(std::string &alias, int signum)
Definition: RunProcManager.cpp:224
YarpRunProcInfo::mCmd
std::string mCmd
Definition: RunProcManager.h:159
YarpRunProcInfo::IsActive
virtual bool IsActive()
Definition: RunProcManager.cpp:126
YarpRunCmdWithStdioInfo::mPidStdout
PID mPidStdout
Definition: RunProcManager.h:292
YarpRunProcInfo::Match
bool Match(std::string &alias)
Definition: RunProcManager.h:123
YarpRunProcInfo::mPidCmd
PID mPidCmd
Definition: RunProcManager.h:153
YarpRunInfoVector::CleanZombie
bool CleanZombie(int zombie)
Definition: RunProcManager.cpp:316
ZombieHunterThread::onStop
void onStop() override
Call-back, called while halting the thread (before join).
Definition: RunProcManager.h:57
YarpRunCmdWithStdioInfo::mWriteToPipeStdinToCmd
FDESC mWriteToPipeStdinToCmd
Definition: RunProcManager.h:304
ZombieHunterThread::ZombieHunterThread
ZombieHunterThread()
Definition: RunProcManager.h:50
YarpRunInfoVector::Add
bool Add(YarpRunProcInfo *process)
Definition: RunProcManager.cpp:194
YarpRunCmdWithStdioInfo::mStdioUUID
std::string mStdioUUID
Definition: RunProcManager.h:302
YARP_UNUSED
#define YARP_UNUSED(var)
Definition: api.h:159
YarpRunInfoVector::m_nProcesses
int m_nProcesses
Definition: RunProcManager.h:192
YarpRunCmdWithStdioInfo::mReadFromPipeStdinToCmd
FDESC mReadFromPipeStdinToCmd
Definition: RunProcManager.h:305
yarp::os::Thread
An abstraction for a thread of execution.
Definition: Thread.h:25
YarpRunProcInfo::YarpRunProcInfo
YarpRunProcInfo(std::string &alias, std::string &on, PID pidCmd, HANDLE handleCmd, bool hold)
Definition: RunProcManager.cpp:86
YarpRunCmdWithStdioInfo::mPidStdin
PID mPidStdin
Definition: RunProcManager.h:291
YarpRunCmdWithStdioInfo::~YarpRunCmdWithStdioInfo
virtual ~YarpRunCmdWithStdioInfo()
Definition: RunProcManager.h:225
YarpRunProcInfo::mOn
std::string mOn
Definition: RunProcManager.h:151
YarpRunInfoVector
Definition: RunProcManager.h:166
ZombieHunterThread::run
void run() override
Main body of the new thread.
Definition: RunProcManager.h:63
YarpRunCmdWithStdioInfo::Clean
bool Clean(PID pid, YarpRunProcInfo *&pRef) override
Definition: RunProcManager.h:237
YarpRunCmdWithStdioInfo::mKillingStdin
bool mKillingStdin
Definition: RunProcManager.h:298
YarpRunProcInfo::Clean
virtual bool Clean(PID pid, YarpRunProcInfo *&pRef)
Definition: RunProcManager.h:125
YarpRunInfoVector::~YarpRunInfoVector
~YarpRunInfoVector()
Definition: RunProcManager.cpp:169
YarpRunInfoVector::Pack
void Pack()
Definition: RunProcManager.cpp:417
ZombieHunterThread::~ZombieHunterThread
virtual ~ZombieHunterThread()
Definition: RunProcManager.h:55
SIGNAL
int SIGNAL(int pid, int signum)
Definition: RunProcManager.cpp:79
YarpRunProcInfo::setEnv
void setEnv(const std::string &env)
Definition: RunProcManager.h:147
YarpRunCmdWithStdioInfo::mKillingStdio
bool mKillingStdio
Definition: RunProcManager.h:297
YarpRunCmdWithStdioInfo::mReadFromPipeCmdToStdout
FDESC mReadFromPipeCmdToStdout
Definition: RunProcManager.h:307
YarpRunCmdWithStdioInfo::Clean
bool Clean() override
Definition: RunProcManager.cpp:507
YarpRunInfoVector::mutex
std::mutex mutex
Definition: RunProcManager.h:186
YarpRunCmdWithStdioInfo::mKillingCmd
bool mKillingCmd
Definition: RunProcManager.h:296
HANDLE
void * HANDLE
Definition: RunProcManager.h:42
ZombieHunterThread::pipe_sync
int pipe_sync[2]
Definition: RunProcManager.h:107
YarpRunCmdWithStdioInfo
Definition: RunProcManager.h:198
YarpRunCmdWithStdioInfo::mCleanStdout
bool mCleanStdout
Definition: RunProcManager.h:294
YarpRunCmdWithStdioInfo::mStdioVector
YarpRunInfoVector * mStdioVector
Definition: RunProcManager.h:309
YarpRunCmdWithStdioInfo::YarpRunCmdWithStdioInfo
YarpRunCmdWithStdioInfo(std::string &alias, std::string &on, std::string &stdio, PID pidCmd, PID pidStdout, FDESC readFromPipeCmdToStdout, FDESC writeToPipeCmdToStdout, HANDLE handleCmd, bool hold)
Definition: RunProcManager.cpp:437
yarp::conf::ssize_t
::ssize_t ssize_t
Definition: numeric.h:60
YarpRunProcInfo::setCmd
void setCmd(const std::string &cmd)
Definition: RunProcManager.h:146
Thread.h
YarpRunInfoVector::Size
int Size()
Definition: RunProcManager.h:171
YarpRunProcInfo::Clean
virtual bool Clean()
Definition: RunProcManager.cpp:144
YarpRunProcInfo::Signal
virtual bool Signal(int signum)
Definition: RunProcManager.cpp:96
YarpRunInfoVector::Killall
int Killall(int signum)
Definition: RunProcManager.cpp:252
YarpRunCmdWithStdioInfo::mKillingStdout
bool mKillingStdout
Definition: RunProcManager.h:299
YarpRunProcInfo::mHandleCmd
HANDLE mHandleCmd
Definition: RunProcManager.h:156
YarpRunCmdWithStdioInfo::TerminateStdio
void TerminateStdio()
Definition: RunProcManager.cpp:600
yarp::os::Thread::isStopping
bool isStopping()
Returns true if the thread is stopping (Thread::stop has been called).
Definition: Thread.cpp:102
PlatformUnistd.h
PlatformSignal.h
CLOSE
int CLOSE(int h)
Definition: RunProcManager.cpp:73
Run.h
ZombieHunterThread
Definition: RunProcManager.h:48
YarpRunProcInfo::~YarpRunProcInfo
virtual ~YarpRunProcInfo()
Definition: RunProcManager.h:119
FDESC
int FDESC
Definition: RunProcManager.h:41
YarpRunInfoVector::MAX_PROCESSES
static const int MAX_PROCESSES
Definition: RunProcManager.h:191
YarpRunCmdWithStdioInfo::mWriteToPipeCmdToStdout
FDESC mWriteToPipeCmdToStdout
Definition: RunProcManager.h:306
YarpRunCmdWithStdioInfo::mStdio
std::string mStdio
Definition: RunProcManager.h:301
YarpRunCmdWithStdioInfo::finalize
void finalize() override
Definition: RunProcManager.h:229
yarp::sig::file::write
bool write(const ImageOf< PixelRgb > &src, const std::string &dest, image_fileformat format=FORMAT_PPM)
Definition: ImageFile.cpp:971
ZombieHunterThread::sigchldHandler
void sigchldHandler()
Definition: RunProcManager.h:100
YarpRunInfoVector::IsRunning
bool IsRunning(std::string &alias)
Definition: RunProcManager.cpp:391
YarpRunProcInfo::mHold
bool mHold
Definition: RunProcManager.h:157
YarpRunProcInfo::mCleanCmd
bool mCleanCmd
Definition: RunProcManager.h:154
Bottle.h
YarpRunProcInfo
Definition: RunProcManager.h:116
PID
pid_t PID
Definition: RunProcManager.h:40
YarpRunInfoVector::m_pStdioMate
YarpRunInfoVector * m_pStdioMate
Definition: RunProcManager.h:194
YarpRunProcInfo::mEnv
std::string mEnv
Definition: RunProcManager.h:160