Skip to content

Instantly share code, notes, and snippets.

@dirvine
Created June 18, 2012 14:22
Show Gist options
  • Save dirvine/2948621 to your computer and use it in GitHub Desktop.
Save dirvine/2948621 to your computer and use it in GitHub Desktop.
boost process test
#include <boost/program_options.hpp>
#include <thread>
#include <chrono>
#include <iostream>
namespace po = boost::program_options;
int main(int ac, char* av[]) {
po::options_description desc("Allowed options");
desc.add_options()
("help", "produce help message")
("runtime", po::value<int>(), "Set runtime in seconds then crash")
("nocrash", "set no crash on runtime ended");
try {
po::variables_map vm;
po::store(po::parse_command_line(ac, av, desc), vm);
po::notify(vm);
if (vm.count("help")) {
std::cout << desc << "\n";
return 1;
} else if (vm.count("runtime")) {
int runtime = vm["runtime"].as<int>();
std::cout << "Running for "
<< runtime << " seconds.\n";
std::this_thread::sleep_for(std::chrono::seconds(runtime));
if (vm.count("nocrash"))
return 0;
else
return 1;
} else {
while(true)
std::this_thread::sleep_for(std::chrono::seconds(1));
}
} catch(std::exception& e) {
std::cout << e.what() << "\n";
return 1;
}
return 0;
}
#include <string>
#include <vector>
#include <thread>
#include "maidsafe/common/test.h"
#include "maidsafe/private/process_manager.h"
namespace maidsafe {
namespace test {
TEST(ProcessManagerTest, BEH_StartSingleProcess) {
maidsafe::ProcessManager manager;
maidsafe::Process test;
ASSERT_TRUE(test.SetProcessName("DUMMYprocess"));
test.AddArgument("DUMMYprocess");
test.AddArgument("--runtime");
test.AddArgument("3");
test.AddArgument("--nocrash");
EXPECT_EQ(0, manager.NumberOfProcesses());
EXPECT_EQ(0, manager.NumberOfLiveProcesses());
EXPECT_EQ(0, manager.NumberOfSleepingProcesses());
uint32_t num = manager.AddProcess(test);
manager.StartProcess(num);
EXPECT_GT(num, 0);
manager.LetProcessDie(num);
EXPECT_EQ(1, manager.NumberOfProcesses());
EXPECT_EQ(0, manager.NumberOfLiveProcesses());
EXPECT_EQ(0, manager.NumberOfSleepingProcesses());
}
} // namespace test
} // namespace maidsafe
int main(int argc, char **argv) {
maidsafe::log::FilterMap filter;
filter["*"] = maidsafe::log::kInfo;
return ExecuteMain(argc, argv, filter);
}
#include <string>
#include <vector>
#include <utility>
#include <thread>
#include <chrono>
#include <algorithm>
#include <boost/process.hpp>
#include <boost/filesystem.hpp>
#include "maidsafe/private/process_manager.h"
namespace maidsafe {
namespace bp = boost::process;
bool Process::SetProcessName(std::string process_name) {
std::string path_string(boost::filesystem::current_path().string());
boost::system::error_code ec;
boost::filesystem3::path proc(process_name);
if (!boost::filesystem3::exists(proc, ec))
return false;
if (!boost::filesystem3::is_regular_file(proc, ec))
return false;
if (ec)
return false;
std::string exec = bp::find_executable_in_path(process_name, path_string);
process_name_ = exec;
return true;
}
void Process::AddArgument(std::string argument) {
args_.push_back(argument);
}
std::string Process::ProcessName() const {
return process_name_;
}
std::vector<std::string> Process::Args() const {
return args_;
}
ProcessManager::ProcessManager() :
processes_(),
process_count_(0),
done_(false) {}
ProcessManager::~ProcessManager() {
TerminateAll();
}
int ProcessManager::AddProcess(Process process) {
ProcessInfo info;
info.process = process;
info.id = ++process_id_;
info.done = false;
// std::thread thd([=] { RunProcess(process_id_); });
// info.thread = std::move(thd);
processes_.push_back(std::move(info));
return process_id_;
}
int32_t ProcessManager::NumberOfProcesses() {
return processes_.size();
}
int32_t ProcessManager::NumberOfLiveProcesses() {
int32_t count(0);
for (auto &i : processes_) {
if(!i.done && i.thread.joinable())
++count;
}
return count;
}
int32_t ProcessManager::NumberOfSleepingProcesses() {
int32_t count(0);
for (auto &i : processes_) {
if(!i.done)
++count;
}
return count;
}
void ProcessManager::RunProcess(int32_t id) {
auto i = FindProcess(id);
if (i == processes_.end())
return;
bp::context ctx;
ctx.environment = bp::self::get_environment();
bp::child c = bp::launch((*i).process.ProcessName(), (*i).process.Args(), ctx);
(*i).child = c;
c.wait();
if (! (*i).done)
RunProcess(id);
}
void ProcessManager::KillProcess(int32_t id) {
auto i = FindProcess(id);
if (i == processes_.end())
return;
(*i).done = true;
(*i).child.terminate(true);
}
void ProcessManager::RestartProcess(int32_t id) {
auto i = FindProcess(id);
if (i == processes_.end())
return;
(*i).done = false;
// (*i).child.terminate(true);
std::thread thd([=] { RunProcess(id); });
(*i).thread = std::move(thd);
}
void ProcessManager::StartProcess(int32_t id) {
auto i = FindProcess(id);
if (i == processes_.end())
return;
(*i).done = false;
std::thread thd([=] { RunProcess(id); });
(*i).thread = std::move(thd);
}
void ProcessManager::LetProcessDie(int32_t id) {
auto i = FindProcess(id);
if (i == processes_.end())
return;
(*i).done = true;
}
std::vector<ProcessInfo>::iterator ProcessManager::FindProcess(int32_t num) {
int32_t id_to_find = num;
return std::find_if(processes_.begin(), processes_.end(),[=] (ProcessInfo &j) {
return (j.id == id_to_find);
});
}
void ProcessManager::TerminateAll() {
for (auto &i : processes_) {
i.done = true;
//i.child.terminate(true);
i.thread.join();
}
processes_.clear();
}
} // namespace maidsafe
#include <boost/process.hpp>
#include <thread>
#include <string>
#include <vector>
namespace maidsafe {
namespace bp = boost::process;
enum class ProcessStatus {
Running,
Stopped,
Crashed
};
class Process {
public:
bool SetProcessName(std::string process_name);
void AddArgument(std::string argument);
std::string ProcessName() const;
std::vector<std::string> Args() const;
private:
std::vector<std::string> args_;
std::string process_name_;
};
struct ProcessInfo {
ProcessInfo() : process(), thread(), id(0), done(false), child() {}
Process process;
std::thread thread;
int32_t id;
bool done;
bp::child child;
};
class ProcessManager {
public:
ProcessManager();
~ProcessManager();
int AddProcess(Process process);
int32_t NumberOfProcesses();
int32_t NumberOfLiveProcesses();
int32_t NumberOfSleepingProcesses();
void StopAndRemoveProcess(Process &process);
ProcessStatus GetProcessStatus(Process &process);
void StartProcess(int32_t id);
void LetProcessDie(int32_t id);
void KillProcess(int32_t id);
void RestartProcess(int32_t id);
private:
ProcessManager(const ProcessManager&);
ProcessManager &operator=(const ProcessManager&);
std::vector<ProcessInfo>::iterator FindProcess(int32_t num);
void RunProcess(int32_t id);
void RunAll();
void MonitorAll();
void TerminateAll();
std::vector<ProcessInfo> processes_;
uint32_t process_count_;
bool done_;
int32_t process_id_;
};
} // namespace maidsafe
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment