redmine

Improved parent/helper death detection

... ... @@ -292,11 +292,40 @@ int syntax() {
int ncpus;
pid_t parent_pid;
int parent_isalive() {
int rc;
debug(12, "parent_pid == %u", parent_pid);
if ((rc=kill(parent_pid, 0))) {
debug(1, "kill(%u, 0) => %i", parent_pid, rc);
return 0;
}
return 1;
}
void child_sigchld() {
debug(1, "Got SIGCHLD (parent ended). Exit.");
exit(-1);
return;
}
int sethandler_sigchld(void (*handler)()) {
struct sigaction sa;
sa.sa_handler = handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
critical_on (sigaction(SIGCHLD, &sa, 0) == -1);
return 0;
}
pid_t myfork() {
pid_t pid = fork();
if (!pid) {
parent_pid = getppid();
sethandler_sigchld(child_sigchld);
# ifdef __linux__
prctl(PR_SET_PDEATHSIG, SIGCHLD);
# endif
... ...
... ... @@ -35,3 +35,6 @@ extern char *parameter_expand(
void *parameter_get_arg
);
extern pid_t myfork();
extern int parent_isalive();
extern int sethandler_sigchld(void (*handler)());
... ...
... ... @@ -742,18 +742,6 @@ void hl_shutdown(int lockid) {
# endif
static inline int parent_isalive() {
int rc;
debug(12, "parent_pid == %u", parent_pid);
if ((rc=kill(parent_pid, 0))) {
debug(1, "kill(%u, 0) => %i", parent_pid, rc);
return 0;
}
return 1;
}
static int helper_isalive_cache;
static inline int helper_isalive() {
int rc;
... ...
... ... @@ -3439,6 +3439,13 @@ l_sync_dump_end:
/* === /DUMP === */
void sync_sigchld() {
debug(9, "");
privileged_check();
return;
}
int *sync_sighandler_exitcode_p = NULL;
int sync_sighandler(sighandler_arg_t *sighandler_arg_p) {
int signal = 0, ret;
... ... @@ -3450,6 +3457,8 @@ int sync_sighandler(sighandler_arg_t *sighandler_arg_p) {
sync_sighandler_exitcode_p = exitcode_p;
sethandler_sigchld(sync_sigchld);
while (state_p == NULL || ((ctx_p->state != STATE_TERM) && (ctx_p->state != STATE_EXIT))) {
debug(3, "waiting for signal");
ret = sigwait(sigset_p, &signal);
... ... @@ -3519,7 +3528,7 @@ int sync_sighandler(sighandler_arg_t *sighandler_arg_p) {
sync_switch_state(pthread_parent, STATE_REHASH);
break;
case SIGCHLD:
privileged_check();
sync_sigchld();
break;
case SIGUSR_THREAD_GC:
sync_switch_state(pthread_parent, STATE_THREAD_GC);
... ...
... ... @@ -48,4 +48,5 @@ extern int sync_prequeue_loadmark
);
extern int sync_prequeue_unload(struct ctx *ctx_p, struct indexes *indexes_p);
extern const char *sync_parameter_get(const char *variable_name, void *_dosync_arg_p);
extern pthread_t pthread_sighandler;
... ...