Blame test/mpi/manual/tchandlers.c

Packit Service c5cf8c
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit Service c5cf8c
/*
Packit Service c5cf8c
 *  (C) 2008 by Argonne National Laboratory.
Packit Service c5cf8c
 *      See COPYRIGHT in top-level directory.
Packit Service c5cf8c
 */
Packit Service c5cf8c
/*
Packit Service c5cf8c
   Define _ISOC99_SOURCE to get snprintf() prototype visible in <stdio.h>
Packit Service c5cf8c
   when it is compiled with --enable-stricttest.
Packit Service c5cf8c
*/
Packit Service c5cf8c
#define _ISOC99_SOURCE
Packit Service c5cf8c
Packit Service c5cf8c
#include <signal.h>
Packit Service c5cf8c
#include <time.h>
Packit Service c5cf8c
#include <pthread.h>
Packit Service c5cf8c
#include <limits.h>
Packit Service c5cf8c
#include <string.h>
Packit Service c5cf8c
#include <unistd.h>
Packit Service c5cf8c
#include <stdio.h>
Packit Service c5cf8c
Packit Service c5cf8c
#include "connectstuff.h"
Packit Service c5cf8c
Packit Service c5cf8c
static char sFnameToDelete[PATH_MAX];
Packit Service c5cf8c
static int sWatchdogTimeout = -1;
Packit Service c5cf8c
static size_t sWatchdogStrokeCount = 0;
Packit Service c5cf8c
Packit Service c5cf8c
static void *threadLooper(void *x)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int runTime = 0;
Packit Service c5cf8c
    size_t lastStrokeSeen = sWatchdogStrokeCount;
Packit Service c5cf8c
    /* allow to run for up to 2 minutes */
Packit Service c5cf8c
    while (runTime < sWatchdogTimeout) {
Packit Service c5cf8c
        safeSleep(5);
Packit Service c5cf8c
        runTime += 5;
Packit Service c5cf8c
        if (lastStrokeSeen == sWatchdogStrokeCount) {
Packit Service c5cf8c
            msg("Watchdog not stroked for a while, printing stack: \n");
Packit Service c5cf8c
            printStackTrace();
Packit Service c5cf8c
        }
Packit Service c5cf8c
        lastStrokeSeen = sWatchdogStrokeCount;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    msg("Watchdog about to abort with a timeout after %d\n", runTime);
Packit Service c5cf8c
    _exit(20);
Packit Service c5cf8c
    return NULL;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
static void term_handler(int sig)
Packit Service c5cf8c
{
Packit Service c5cf8c
    msg("removing file: %s\n", sFnameToDelete);
Packit Service c5cf8c
    unlink(sFnameToDelete);
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
static void segv_handler(int sig)
Packit Service c5cf8c
{
Packit Service c5cf8c
    msg("SEGV detected!\n");
Packit Service c5cf8c
    printStackTrace();
Packit Service c5cf8c
    _exit(10);
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void indicateConnectSucceeded(void)
Packit Service c5cf8c
{
Packit Service c5cf8c
    char fnameToCreate[PATH_MAX];
Packit Service c5cf8c
    FILE *fp;
Packit Service c5cf8c
    snprintf(fnameToCreate, PATH_MAX, "%s.done", sFnameToDelete);
Packit Service c5cf8c
    msg("Creating file: %s\n", fnameToCreate);
Packit Service c5cf8c
    fp = fopen(fnameToCreate, "wt");
Packit Service c5cf8c
    if (fp != NULL) {
Packit Service c5cf8c
        fclose(fp);
Packit Service c5cf8c
    }
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void startWatchdog(int seconds)
Packit Service c5cf8c
{
Packit Service c5cf8c
    pthread_t theThread;
Packit Service c5cf8c
    sWatchdogTimeout = seconds;
Packit Service c5cf8c
    msg("Starting watchdog - timeout in %d\n", seconds);
Packit Service c5cf8c
    pthread_create(&theThread, NULL, threadLooper, NULL);
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void strokeWatchdog()
Packit Service c5cf8c
{
Packit Service c5cf8c
    sWatchdogStrokeCount++;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void installSegvHandler(void)
Packit Service c5cf8c
{
Packit Service c5cf8c
    struct sigaction new_action;
Packit Service c5cf8c
    new_action.sa_handler = segv_handler;
Packit Service c5cf8c
    sigemptyset(&new_action.sa_mask);
Packit Service c5cf8c
    new_action.sa_flags = 0;
Packit Service c5cf8c
    sigaction(SIGSEGV, &new_action, NULL);
Packit Service c5cf8c
    msg("Installed SEGV handler\n");
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void installExitHandler(const char *fname)
Packit Service c5cf8c
{
Packit Service c5cf8c
    /* Install signal handler */
Packit Service c5cf8c
    struct sigaction new_action;
Packit Service c5cf8c
    if (strlen(fname) > PATH_MAX) {
Packit Service c5cf8c
        msg("Fname: <%s> too long - aborting", fname);
Packit Service c5cf8c
        _exit(12);
Packit Service c5cf8c
    }
Packit Service c5cf8c
    strncpy(sFnameToDelete, fname, PATH_MAX);
Packit Service c5cf8c
    new_action.sa_handler = term_handler;
Packit Service c5cf8c
    sigemptyset(&new_action.sa_mask);
Packit Service c5cf8c
    new_action.sa_flags = 0;
Packit Service c5cf8c
    sigaction(SIGINT, &new_action, NULL);
Packit Service c5cf8c
    sigaction(SIGTERM, &new_action, NULL);
Packit Service c5cf8c
    msg("Installed signal handlers\n");
Packit Service c5cf8c
}