overseer.cpp File Reference

#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"
Include dependency graph for overseer.cpp:

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 Documentation

#define PROCESS_LOG_STOP

Function Documentation

void check_death_pids (  ) 
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 (  ) 
void overseer_child_died ( int  sig,
siginfo_t *  info,
void *  hu 
)
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.

References Debug(), Error(), spawn(), and status.

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().


Variable Documentation

struct sigaction child_died_signal

Referenced by init_process_overseer().

int from_main
int main_pid
PollDelay overseer_delay(0, 5000, 250000)
struct sigaction pipe_signal

Referenced by init_process_overseer().

map<int,Process*> processes

Referenced by poll_death(), and request_spawn().

Lock pulling

Referenced by poll_death().

map<int,int> realpid2mainpid
vector<ExitStatus>* realpidsdied = NULL
int to_main
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by  doxygen 1.6.2