MIRA
ProcessSpawnManager.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 by
3  * MetraLabs GmbH (MLAB), GERMANY
4  * and
5  * Neuroinformatics and Cognitive Robotics Labs (NICR) at TU Ilmenau, GERMANY
6  * All rights reserved.
7  *
8  * Contact: info@mira-project.org
9  *
10  * Commercial Usage:
11  * Licensees holding valid commercial licenses may use this file in
12  * accordance with the commercial license agreement provided with the
13  * software or, alternatively, in accordance with the terms contained in
14  * a written agreement between you and MLAB or NICR.
15  *
16  * GNU General Public License Usage:
17  * Alternatively, this file may be used under the terms of the GNU
18  * General Public License version 3.0 as published by the Free Software
19  * Foundation and appearing in the file LICENSE.GPL3 included in the
20  * packaging of this file. Please review the following information to
21  * ensure the GNU General Public License version 3.0 requirements will be
22  * met: http://www.gnu.org/copyleft/gpl.html.
23  * Alternatively you may (at your option) use any later version of the GNU
24  * General Public License if such license has been publicly approved by
25  * MLAB and NICR (or its successors, if any).
26  *
27  * IN NO EVENT SHALL "MLAB" OR "NICR" BE LIABLE TO ANY PARTY FOR DIRECT,
28  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
29  * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF "MLAB" OR
30  * "NICR" HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * "MLAB" AND "NICR" SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
33  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
34  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
35  * ON AN "AS IS" BASIS, AND "MLAB" AND "NICR" HAVE NO OBLIGATION TO
36  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS.
37  */
38 
39 
47 #ifndef _MIRA_PROCESSSPAWNMANAGER_H_
48 #define _MIRA_PROCESSSPAWNMANAGER_H_
49 
50 #include <list>
51 #include <vector>
52 
53 #include <boost/algorithm/string.hpp>
54 
55 #include <error/Logging.h>
56 
57 #include <utils/Foreach.h>
58 #include <utils/Path.h>
59 #include <utils/PathFinder.h>
60 
61 #include <thread/ThreadMonitor.h>
62 
63 #include <platform/Process.h>
64 
65 namespace mira {
66 
68 
74 {
75 public:
76 
77  struct ProcessInfo
78  {
80  {
81  if(!cleanup_cmd.empty() && std::system(NULL)) {
82  if (0 != std::system(cleanup_cmd.c_str())) {
83  MIRA_LOG(WARNING) << "ProcessSpawnManager: Failed to clean up using command '" << cleanup_cmd << "'";
84  }
85  }
86  }
87 
88  std::string getName() const {
89  if(name.empty())
90  return pid;
91  else
92  return name;
93  }
94 
96 
97  std::string name;
98  std::string pid;
99  bool respawn;
100  bool required;
101 
102  // infos for respawn
104  Path executable; // the used executable
105  std::vector<std::string> args; // arguments of the process
106  boost::optional<Process::Environment> env;
107  std::string cleanup_cmd;
108  };
109  typedef boost::shared_ptr<ProcessInfo> ProcessInfoPtr;
110 
111  std::list<ProcessInfoPtr> mProcesses;
112 
113  boost::thread mWatchdogThread;
114  boost::mutex mMutex;
115 
116  typedef boost::function<void(const ProcessInfo& p)> RequiredProcessTerminatedFn;
117 
119 
120 public:
122  {
123  mWatchdogThread.interrupt();
124  mWatchdogThread.join();
125  }
126 
127  void startProcess(const Path& executable, const std::vector<std::string>& args,
128  const std::string& name = "",
129  bool respawn=false, bool required=false,
130  bool shutdownRecursively=false,
131  boost::optional<Process::Environment> env = boost::optional<Process::Environment>(),
132  const std::string& cleanupCmd="")
133  {
134  ProcessInfoPtr info(new ProcessInfo);
135 
136  // store infos
137  info->name = name;
138  info->respawn = respawn;
139  info->required = required;
140 
142  if (shutdownRecursively)
144 
145  // launch the new process
146  info->process = Process::createProcess(executable.string(), args,
147  flags,
148  Process::none, env);
149  info->pid = toString(info->process.getPID());
150 
151  info->shutdownRecursively = shutdownRecursively;
152  info->executable = executable;
153  info->args = args;
154  info->env = env;
155  info->cleanup_cmd = cleanupCmd;
156 
157  // synchronize
158  {
159  boost::mutex::scoped_lock lock(mMutex);
160  mProcesses.push_back(info);
161  }
162  }
163 
165  {
167  // start watchdog thread that respawns processes when they terminate
168  // if not yet running
169  if(mWatchdogThread.get_id()==boost::thread::id())
170  mWatchdogThread = boost::thread(&ProcessSpawnManager::watchdog, this);
171  }
172 
173  void watchdog()
174  {
176  ThreadMonitor::instance().addThisThread("#ProcessSpawnManager Watchdog");
177 
178  while(!boost::this_thread::interruption_requested()) {
179  boost::this_thread::sleep(Duration::seconds(1));
180 
181  boost::mutex::scoped_lock lock(mMutex);
182  foreach(ProcessInfoPtr info, mProcesses)
183  {
184  if(info->process.isRunning())
185  continue; // process is still running, nothing to do
186 
187  MIRA_LOG(NOTICE) << "Process '" << info->getName() << "' "
188  << "was terminated.";
189  // if we reach here, the process was stopped and we need
190  // to respawn it or terminate ourselves
191  if(info->respawn) {
193  if (info->shutdownRecursively)
195  MIRA_LOG(NOTICE) << "Respawning: " << info->getName();
196  info->process = Process::createProcess(info->executable.string(), info->args,
197  flags,
198  Process::none, info->env);
199  info->pid = toString(info->process.getPID());
200  } else if(info->required) {
203  }
204  }
205  }
207  ThreadMonitor::instance().removeThisThread();
208  }
209 
210 };
211 
213 
214 } // namespace
215 
216 #endif
Macro for iterating over all elements in a container.
Different functions for searching files or directories.
static Process createProcess(const std::string &commandLine, CreationFlags flags, RedirectionFlags streamRedirection=none)
Spawns a new process and executes the given command line.
Definition: Process.h:221
boost::mutex mMutex
Definition: ProcessSpawnManager.h:114
Header including various log headers.
static Type & instance()
Returns a reference to the singleton instance.
Definition: Singleton.h:544
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
boost::filesystem::path Path
Typedef of a Path (shorter version for boost::filesystem::path)
Definition: Path.h:69
A thread monitor, which collects information about the resources of all running threads of the curren...
bool shutdownRecursively
Definition: ProcessSpawnManager.h:103
boost::thread mWatchdogThread
Definition: ProcessSpawnManager.h:113
~ProcessInfo()
Definition: ProcessSpawnManager.h:79
Implements manager that starts processes and keeps track of them in order to respawn them if required...
Definition: ProcessSpawnManager.h:73
#define MIRA_LOG(level)
Use this macro to log data.
Definition: LoggingCore.h:529
boost::function< void(const ProcessInfo &p)> RequiredProcessTerminatedFn
Definition: ProcessSpawnManager.h:116
std::string name
Definition: ProcessSpawnManager.h:97
boost::optional< Process::Environment > env
Definition: ProcessSpawnManager.h:106
static bool isDestroyed()
Returns true, if the singleton was already destroyed.
Definition: Singleton.h:552
Encapsulates a process, that was launched from the current process.
Definition: Process.h:96
std::string toString(const T &value, int precision=-1)
Converts any data type to string (the data type must support the stream << operator).
Definition: ToString.h:256
std::list< ProcessInfoPtr > mProcesses
Definition: ProcessSpawnManager.h:111
std::string getName() const
Definition: ProcessSpawnManager.h:88
Path executable
Definition: ProcessSpawnManager.h:104
sec_type seconds() const
Returns normalized number of seconds (0..59)
Definition: Time.h:280
std::vector< std::string > args
Definition: ProcessSpawnManager.h:105
bool required
Definition: ProcessSpawnManager.h:100
Definition: ProcessSpawnManager.h:77
RequiredProcessTerminatedFn mRequiredProcessTerminatedFn
Definition: ProcessSpawnManager.h:118
boost::shared_ptr< ProcessInfo > ProcessInfoPtr
Definition: ProcessSpawnManager.h:109
CreationFlags
Definition: Process.h:205
If true, shutdown will determine the complete progeny of the spawned process and eradicate it (top do...
Definition: Process.h:215
std::string cleanup_cmd
Definition: ProcessSpawnManager.h:107
void watchdog()
Definition: ProcessSpawnManager.h:173
Definition: LoggingCore.h:76
Functions for modifying file system paths.
Platform independent system calls.
std::string pid
Definition: ProcessSpawnManager.h:98
void startWatchdog(RequiredProcessTerminatedFn fn=RequiredProcessTerminatedFn())
Definition: ProcessSpawnManager.h:164
Process process
Definition: ProcessSpawnManager.h:95
void startProcess(const Path &executable, const std::vector< std::string > &args, const std::string &name="", bool respawn=false, bool required=false, bool shutdownRecursively=false, boost::optional< Process::Environment > env=boost::optional< Process::Environment >(), const std::string &cleanupCmd="")
Definition: ProcessSpawnManager.h:127
Will send the SIGINT signal to the child when the parent gets killed.
Definition: Process.h:209
bool respawn
Definition: ProcessSpawnManager.h:99
~ProcessSpawnManager()
Definition: ProcessSpawnManager.h:121
Definition: LoggingCore.h:77