Version 0.0.1 fixing issues.

This commit is contained in:
unrealdragon 2026-05-14 17:06:59 +05:30
commit cc12b4765c
4 changed files with 55 additions and 42 deletions

View file

@ -4,7 +4,7 @@
#include <sstream> #include <sstream>
AppInfo::~AppInfo() { AppInfo::~AppInfo() {
std::cout << "Module: " << getModuleName() << " finished ops." << std::endl; std::cout << "Module: " << getModuleName() << " finished ops." << std::endl;
} }
void AppInfo::setProgramName(std::string name) void AppInfo::setProgramName(std::string name)
@ -66,7 +66,7 @@ bool AppInfo::isParentDependencyCleared(std::osyncstream &out) const
{ {
for(auto &[key, value]: parents) { for(auto &[key, value]: parents) {
if(key->getState() != value) { if(key->getState() != value) {
out << key->getModuleName() << " not at state: " << stateToString(state) << out << key->getModuleName() << " not at state: " << stateToString(value) <<
" but is at:" << stateToString(key->getState()) << std::endl; " but is at:" << stateToString(key->getState()) << std::endl;
return false; return false;
} }
@ -130,6 +130,7 @@ void AppInfo::copyFromData(AppInfo::AppData &other)
for(auto &i: other.args) { for(auto &i: other.args) {
this->args.push_back(i); this->args.push_back(i);
} }
this->after = other.after;
setRunMode(other.run_mode); setRunMode(other.run_mode);
} }
@ -187,7 +188,8 @@ void AppInfo::printInfo(std::ostream &out)
ss << key << "[" << value << "], "; ss << key << "[" << value << "], ";
} }
std::string after = ss.str(); std::string after = ss.str();
after = after.substr(0,after.size() - 2); if(!after.empty() && after.size() >= 2)
after = after.substr(0,after.size() - 2);
out << "After: " << after << std::endl; out << "After: " << after << std::endl;
std::stringstream ss2; std::stringstream ss2;
for(auto &[key, value]: parents) { for(auto &[key, value]: parents) {
@ -263,7 +265,8 @@ void AppInfo::AppData::printInfo(std::ostream &out)
ss << key << "[" << value << "], "; ss << key << "[" << value << "], ";
} }
std::string after = ss.str(); std::string after = ss.str();
after = after.substr(0,after.size() - 2); if(!after.empty() && after.size() >= 2)
after = after.substr(0,after.size() - 2);
out << "After: " << after << std::endl; out << "After: " << after << std::endl;
out << "Create Log: " << AppData::create_log << std::endl; out << "Create Log: " << AppData::create_log << std::endl;
out << "************************************End************************************" << std::endl; out << "************************************End************************************" << std::endl;

View file

@ -7,6 +7,7 @@
#include <memory> #include <memory>
#include <unordered_map> #include <unordered_map>
#include <syncstream> #include <syncstream>
#include <atomic>
class AppInfo class AppInfo
{ {
@ -42,7 +43,7 @@ private:
string_map after; string_map after;
bool create_log = false; bool create_log = false;
std::unordered_map<std::shared_ptr<AppInfo>, State> parents; std::unordered_map<std::shared_ptr<AppInfo>, State> parents;
State state = State::initial; std::atomic<State> state{State::initial};
RunMode mode = RunMode::script; RunMode mode = RunMode::script;
public: public:
void setProgramName(std::string name); void setProgramName(std::string name);

View file

@ -47,10 +47,9 @@ void ExecutionManager::run()
{ {
finished = false; finished = false;
initial_list_size = job_list.size(); initial_list_size = job_list.size();
while(!job_list.empty()) { while(true) {
for(int i=active_thread_count.load(); i < threads ;i++) { for(int i=active_thread_count.load(); i < threads ;i++) {
int val = 0; int val = 0;
active_thread_count.fetch_add(1);
{ {
std::lock_guard<std::mutex> lock_get(this->job_list_mutex); std::lock_guard<std::mutex> lock_get(this->job_list_mutex);
val = index_count++; val = index_count++;
@ -63,6 +62,7 @@ void ExecutionManager::run()
break; break;
} }
} }
active_thread_count.fetch_add(1);
std::shared_ptr<std::thread> thread = std::make_shared<std::thread>([this, val](){ std::shared_ptr<std::thread> thread = std::make_shared<std::thread>([this, val](){
std::shared_ptr<AppInfo> ptr; std::shared_ptr<AppInfo> ptr;
std::osyncstream os(log_file.rdbuf()); std::osyncstream os(log_file.rdbuf());
@ -107,12 +107,17 @@ void ExecutionManager::run()
bool create_log = ptr->getCreateLog(); bool create_log = ptr->getCreateLog();
std::deque<std::string> pargs = ptr->getArgs(); std::deque<std::string> pargs = ptr->getArgs();
int total_args = pargs.size() + 2; int total_args = pargs.size() + 2;
char *args[total_args]; std::vector<char*> args(total_args);
args[0] = program_name.data(); args[0] = program_name.data();
for(int i=1,index=0; index < pargs.size(); i++,index++) { for(int i=1,index=0; index < pargs.size(); i++,index++) {
args[i] = pargs[index].data(); args[i] = pargs[index].data();
} }
args[total_args - 1] = (char *)NULL; args[total_args - 1] = (char *)NULL;
bool log_file_exists = std::filesystem::exists(program_log_file);
long long size = 0;
if(log_file_exists)
size = std::filesystem::file_size(program_log_file);
// Do fork and run // Do fork and run
auto pid = fork(); auto pid = fork();
FILE *popen_file = nullptr; FILE *popen_file = nullptr;
@ -120,44 +125,40 @@ void ExecutionManager::run()
case 0: { case 0: {
if(!dir.empty()) { if(!dir.empty()) {
int err = chdir(dir.c_str()); int err = chdir(dir.c_str());
if(err != 0) {
os << "Child changing dir failed: " << err << std::endl;
}
} }
os << "Child running: " << program_name << " with args: " << args << std::endl;
bool log_file_exists = std::filesystem::exists(program_log_file);
if(create_log) { if(create_log) {
int output_fd = -99; int output_fd = -99;
if(!log_file_exists) if(!log_file_exists)
output_fd = open(program_log_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); output_fd = open(program_log_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
else { else {
auto size = std::filesystem::file_size(program_log_file);
if(size < log_file_max_size) if(size < log_file_max_size)
{ {
output_fd = open(program_log_file.c_str(), O_WRONLY | O_APPEND, S_IRUSR | S_IWUSR); output_fd = open(program_log_file.c_str(), O_WRONLY | O_APPEND, S_IRUSR | S_IWUSR);
} }
else { else {
output_fd = open(program_log_file.c_str(), O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR); output_fd = open(program_log_file.c_str(), O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
os << "Truncating log file: " << program_log_file << std::endl;
} }
} }
if (output_fd < 0) { if (output_fd < 0) {
std::cout << "Failed to open log file " << program_log_file << ":" _exit(3);
<< std::endl;
std::perror("open");
std::exit(1);
} }
if (dup2(output_fd, STDOUT_FILENO) < 0) { if (dup2(output_fd, STDOUT_FILENO) < 0) {
std::perror("dup2 (stdout)"); _exit(3);
std::exit(1);
} }
if (dup2(output_fd, STDERR_FILENO) < 0) { if (dup2(output_fd, STDERR_FILENO) < 0) {
std::perror("dup2 (stderr)"); _exit(3);
std::exit(1);
} }
close(output_fd);
} }
execv(program_name.c_str(), args); execv(program_name.c_str(), args.data());
exit(0); _exit(1);
}
case -1: {
os << "Fork failed for module: " << module_name << std::endl;
ptr->setFinished(); // Or a dedicated failed state
state_change.fetch_add(1);
state_change.notify_all();
break;
} }
default: { default: {
// After fork in parent do // After fork in parent do
@ -174,27 +175,32 @@ void ExecutionManager::run()
if(mode == AppInfo::RunMode::script) { if(mode == AppInfo::RunMode::script) {
os << "Run mode is script so will wait for child to finish: " << module_name << std::endl; os << "Run mode is script so will wait for child to finish: " << module_name << std::endl;
int wait = waitpid(pid, &status, WUNTRACED); int wait = waitpid(pid, &status, WUNTRACED);
ptr->setFinished();
os << "Parent wait finished: " << wait << " child status: " << status << std::endl; os << "Parent wait finished: " << wait << " child status: " << status << std::endl;
} }
// Set finished // Set finished
ptr->setFinished();
state_change.fetch_add(1); state_change.fetch_add(1);
state_change.notify_all(); state_change.notify_all();
os << std::vformat("Thread[{}] finished: ", std::make_format_args(val)) os << std::vformat("Thread[{}] finished: ", std::make_format_args(val))
<< module_name<< std::endl; << module_name<< std::endl;
active_thread_count.fetch_min(1); active_thread_count.fetch_sub(1);
}); });
thread_list.push_back(thread); thread_list.push_back(thread);
} }
std::lock_guard<std::mutex> lock_get(this->job_list_mutex); {
if(job_list.empty()) { std::lock_guard<std::mutex> lock_get(this->job_list_mutex);
log_file << "Main Thread: Job list is empty, waiting for finish." << std::endl; if(job_list.empty()) {
break; log_file << "Main Thread: Job list is empty, waiting for finish." << std::endl;
break;
}
if((index_count) > (initial_list_size - 1)) {
log_file << "Main Thread: All jobs queued." << std::endl;
break;
}
} }
if((index_count) > (initial_list_size - 1)) { if (active_thread_count.load() >= threads) {
log_file << "Main Thread: All jobs queued." << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(10));
break;
} }
} }
for(auto i: thread_list) { for(auto i: thread_list) {

View file

@ -178,7 +178,7 @@ void parseArgs(int c, char *v[]) {
int i = contains(arg_list, "--json", "-j"); int i = contains(arg_list, "--json", "-j");
if(i >= 0) { if(i >= 0) {
int j = i + 1; int j = i + 1;
if(j > c) { if(j > arg_list.size()) {
printHelp(); printHelp();
exit(-1); exit(-1);
} }
@ -189,7 +189,7 @@ void parseArgs(int c, char *v[]) {
i = contains(arg_list, "--log_dir", "-ld"); i = contains(arg_list, "--log_dir", "-ld");
if(i >= 0) { if(i >= 0) {
int j = i + 1; int j = i + 1;
if(j > c) { if(j > arg_list.size()) {
printHelp(); printHelp();
exit(-1); exit(-1);
} }
@ -200,7 +200,7 @@ void parseArgs(int c, char *v[]) {
i = contains(arg_list, "--threads", "-t"); i = contains(arg_list, "--threads", "-t");
if(i >= 0) { if(i >= 0) {
int j = i + 1; int j = i + 1;
if(j > c) { if(j > arg_list.size()) {
printHelp(); printHelp();
exit(-1); exit(-1);
} }
@ -211,7 +211,7 @@ void parseArgs(int c, char *v[]) {
i = contains(arg_list, "--help", "-h"); i = contains(arg_list, "--help", "-h");
if(i >= 0) { if(i >= 0) {
int j = i + 1; int j = i + 1;
if(j > c) { if(j > arg_list.size()) {
printHelp(); printHelp();
exit(-1); exit(-1);
} }
@ -237,7 +237,7 @@ std::string string_strip(std::string str) {
bool front_found = false; bool front_found = false;
for(int i=0; i<str.size(); i++) { for(int i=0; i<str.size(); i++) {
if(!front_found) { if(!front_found) {
if(str[i] == ' ' || str[i] == '\t' || str[i] == '\n' || str[i] == '\v') if(str[i] == ' ' || str[i] == '\t' || str[i] == '\n' || str[i] == '\v' || str[i] == '\r')
continue; continue;
else { else {
front_found = true; front_found = true;
@ -248,7 +248,7 @@ std::string string_strip(std::string str) {
else else
ch += str[i]; ch += str[i];
} }
auto pos = ch.find_last_not_of(" "); auto pos = ch.find_last_not_of(" \t\n\v\r");
if(pos == std::string::npos) if(pos == std::string::npos)
return ch; return ch;
ch.erase(pos+1); ch.erase(pos+1);
@ -321,8 +321,8 @@ std::optional<int> checkAppList(std::deque<AppInfo::AppData> &copy_list, std::ve
int reshuffle_count = 0; int reshuffle_count = 0;
while(copy_list.size() != 0) { while(copy_list.size() != 0) {
size_t copy_list_size = copy_list.size(); size_t copy_list_size = copy_list.size();
for(auto item = copy_list.begin(); item != copy_list.end(); item++) { for(auto item = copy_list.begin(); item != copy_list.end();) {
if(item->getAfterString().size() == 0) { if(item->after.size() == 0) {
std::shared_ptr<AppInfo> app_info = std::make_shared<AppInfo>(); std::shared_ptr<AppInfo> app_info = std::make_shared<AppInfo>();
app_info->copyFromData(*item); app_info->copyFromData(*item);
after_list.push_back(std::move(app_info)); after_list.push_back(std::move(app_info));
@ -364,6 +364,9 @@ std::optional<int> checkAppList(std::deque<AppInfo::AppData> &copy_list, std::ve
reshuffle_count = 0; reshuffle_count = 0;
item = copy_list.erase(item); item = copy_list.erase(item);
} }
else {
item++;
}
if(copy_list.size() == 0 || item == copy_list.end()) if(copy_list.size() == 0 || item == copy_list.end())
break; break;
} }