#include <cstdio>#include <fcntl.h>#include <stdlib.h>#include <sys/types.h>#include <sys/wait.h>#include <stdio.h>#include <assert.h>#include <errno.h>#include <unistd.h>#include <string.h>#include <iostream>#include <signal.h>#include <stdarg.h>#include <map>#include <set>#include "Active/lock.h"#include "overseer.h"
Classes | |
| class | ForkQuick |
Defines | |
| #define | PROCESS_LOG_STOP |
Functions | |
| vector< ExitStatus > * | take_death_pids () |
| void | return_death_pids (vector< ExitStatus > *r) |
| void | process_death_pids () |
| void | spawn_request (char *str) |
| void | process_main_request (char *str) |
| void | check_death_pids () |
| void | listen_to_main_requests () |
| void | overseer_child_died (int sig, siginfo_t *info, void *hu) |
| void | send_overseer_request (char *str) |
| bool | poll_death () |
| int | request_spawn (const char *str, Process *target) |
| int | spawn (const char *str, const char *description, Process *target) |
| int | spawn (const char *str, const char *descr) |
| ExitStatus | exec (const char *script, const char *description) |
| void | init_process_overseer () |
Variables | |
| int | from_main |
| int | to_main |
| int | to_overseer |
| int | from_overseer |
| int | main_pid |
| map< int, int > | realpid2mainpid |
| vector< ExitStatus > * | realpidsdied = NULL |
| PollDelay | overseer_delay (0, 5000, 250000) |
| struct sigaction | child_died_signal |
| struct sigaction | pipe_signal |
| map< int, Process * > | processes |
| Lock | pulling |
| ForkQuick | order_matters |
| #define PROCESS_LOG_STOP |
| void check_death_pids | ( | ) |
References overseer_delay, process_death_pids(), and PollDelay::wait().
Referenced by listen_to_main_requests().
| ExitStatus exec | ( | const char * | script, | |
| const char * | description | |||
| ) |
Performs a synchronous execution of the exec process
References Debug(), Process::exec(), Process::exitstatus, Fatal(), ExitStatus::pid, ExitStatus::status, and status.
| void init_process_overseer | ( | ) |
This must be called at the beginning of the program. It will fork of a new process. The child will continue with the main operation while the parent will listen to any potential process start requests.
We need to be able to catch the death signal of the main before we fork, afterward we might be too late
We are the child and should simply continue with the rest of the program.
This is the overseer process
References assert(), child_died_signal, from_main, from_overseer, listen_to_main_requests(), main_pid, overseer_child_died(), pipe_signal, to_main, and to_overseer.
Referenced by ForkQuick::ForkQuick().
| void listen_to_main_requests | ( | ) |
References assert(), check_death_pids(), from_main, i, overseer_delay, process_main_request(), and PollDelay::reset().
Referenced by init_process_overseer().
| void overseer_child_died | ( | int | sig, | |
| siginfo_t * | info, | |||
| void * | hu | |||
| ) |
References ExitStatus::pid, return_death_pids(), ExitStatus::status, and take_death_pids().
Referenced by init_process_overseer().
| bool poll_death | ( | ) |
This function will check whether there is any process that ended its life so far. If so, it will call that process with died() So the thread will jump from the poll_Death function to any of the died calls in a process. This is important for Qt since a random thread indirectly started through an exec might end up in the user interface thread. As such it is very important to check the process end status independently before proceeding in Qt.
References assert(), from_overseer, i, ExitStatus::pid, processes, pulling, and ExitStatus::status.
Referenced by Process::exec(), main(), and SongSelectorLogic::timerTick().
| void process_death_pids | ( | ) |
If the main process receives a SIGINT it indicates that it was interrupted in a debugger, I believe
References assert(), ExitStatus::exit(), ExitStatus::exited(), ExitStatus::interrupted(), main_pid, ExitStatus::pid, realpid2mainpid, sprintf(), ExitStatus::status, status, ExitStatus::statusText(), take_death_pids(), and to_main.
Referenced by check_death_pids().
| void process_main_request | ( | char * | str | ) |
References assert(), and spawn_request().
Referenced by listen_to_main_requests().
| int request_spawn | ( | const char * | str, | |
| Process * | target | |||
| ) |
References assert(), processes, send_overseer_request(), and sprintf().
Referenced by spawn().
| void return_death_pids | ( | vector< ExitStatus > * | r | ) |
This is tricky since there can only be one signal handler processing the data, meaning that if we return it, the old value should always have been NULL
References assert(), and realpidsdied.
Referenced by overseer_child_died().
| void send_overseer_request | ( | char * | str | ) |
References to_overseer.
Referenced by request_spawn().
| int spawn | ( | const char * | , | |
| const char * | descr | |||
| ) |
Will branch of a new process to execute the provided script. The return value is a local process id of the child.
A vfork should work slightly faster We don't care about a new task structure anyway
If we use exit instead of _exit our own static data structures will be destroyed ! Of course this routine is only necessary when there was an error becoming something else.
| int spawn | ( | const char * | str, | |
| const char * | description, | |||
| Process * | target | |||
| ) |
References request_spawn().
| void spawn_request | ( | char * | str | ) |
References assert(), i, and realpid2mainpid.
Referenced by process_main_request().
| vector<ExitStatus>* take_death_pids | ( | ) |
References realpidsdied.
Referenced by overseer_child_died(), and process_death_pids().
| struct sigaction child_died_signal |
Referenced by init_process_overseer().
| int from_main |
Referenced by init_process_overseer(), and listen_to_main_requests().
| int from_overseer |
Referenced by init_process_overseer(), and poll_death().
| int main_pid |
Referenced by init_process_overseer(), and process_death_pids().
| PollDelay overseer_delay(0, 5000, 250000) |
Referenced by check_death_pids(), and listen_to_main_requests().
| struct sigaction pipe_signal |
Referenced by init_process_overseer().
Referenced by poll_death(), and request_spawn().
| Lock pulling |
Referenced by poll_death().
| map<int,int> realpid2mainpid |
Referenced by process_death_pids(), and spawn_request().
| vector<ExitStatus>* realpidsdied = NULL |
Referenced by return_death_pids(), and take_death_pids().
| int to_main |
Referenced by init_process_overseer(), and process_death_pids().
| int to_overseer |
Referenced by init_process_overseer(), and send_overseer_request().
1.6.2