Created
June 18, 2012 14:22
-
-
Save dirvine/2948621 to your computer and use it in GitHub Desktop.
boost process test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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