diff --git a/src/actsim_agent/worker.cpp b/src/actsim_agent/worker.cpp index f81aa6a..bb7ed22 100644 --- a/src/actsim_agent/worker.cpp +++ b/src/actsim_agent/worker.cpp @@ -105,14 +105,79 @@ void Worker::thread_run() { } std::unique_ptr Worker::perform_task(std::unique_ptr& task, bool& finished) { - usleep(10000000); std::cout << "[WORKER] Worker performed task. Please implement me!" << std::endl; - task->id; finished = true; - return std::make_unique(); + if (task->get_content().size() != 1) { + std::cerr << "Error: Simulation configuration in worker thread has more than one testcases to run!" << std::endl; + finished = false; + return std::make_unique(); + } + + auto testcase = task->get_content().front(); + + // execv expects mutable char*, so we have to copy our stuff first + auto design = this->interface.get_design(task->design); + char *design_char = new char[design.length()+1]; + std::strcpy(design_char, design.c_str()); + + char *top_proc_char = new char[testcase.top.length() + 1]; + std::strcpy(top_proc_char, testcase.top.c_str()); + + auto commands = testcase.commands; + + std::cout << "[WORKER] Here's the copied design string: " << design_char << std::endl; + std::cout << "[WORKER] Here's the copied top string: " << top_proc_char << std::endl; + usleep(10000000); + + return std::make_unique(); // wait for either the executing process to finish or // for the condition variable indicating the process should be stopped + int stdin_pipe[2]; + int stdout_pipe[2]; + int stderr_pipe[2]; + + pipe(stdin_pipe); + pipe(stdout_pipe); + pipe(stderr_pipe); + + // Time to have an identity crisis. + // I'd like to see this as one of those comic tropes; person gets split into + // a good and the bad self. Like the normal one and the evil clone. + // Which side are we? The normal or the evil clone? + if (!fork()) { + // Oh no, we're the evil clone! + // Just kidding, we're the child process + + // redirect stdout, stdin, and stderr + dup2(stdin_pipe[0], STDIN_FILENO); + dup2(stdout_pipe[1], STDOUT_FILENO); + dup2(stderr_pipe[1], STDERR_FILENO); + + // close all the initial file descriptors so actsim (which we're about to call) + // doesn't know what's going on + close(stdin_pipe[0]); + close(stdin_pipe[1]); + close(stdout_pipe[0]); + close(stdout_pipe[1]); + close(stderr_pipe[0]); + close(stderr_pipe[1]); + + // build the execution vector + char* const argv[] = {"${ACT_HOME}/bin/actsim", design_char, top_proc_char}; + + // and call actsim + execv(argv[0], argv); + + // we shouldn't land here + + } else { + // stuff for the main process + } + + delete design_char; + delete top_proc_char; + } void Worker::run_actsim() {