File: tchandlers.c

package info (click to toggle)
mpich 4.0.2-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 423,384 kB
  • sloc: ansic: 1,088,434; cpp: 71,364; javascript: 40,763; f90: 22,829; sh: 17,463; perl: 14,773; xml: 14,418; python: 10,265; makefile: 9,246; fortran: 8,008; java: 4,355; asm: 324; ruby: 176; lisp: 19; php: 8; sed: 4
file content (111 lines) | stat: -rw-r--r-- 2,749 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
 * Copyright (C) by Argonne National Laboratory
 *     See COPYRIGHT in top-level directory
 */

/*
   Define _ISOC99_SOURCE to get snprintf() prototype visible in <stdio.h>
   when it is compiled with --enable-stricttest.
*/
#define _ISOC99_SOURCE

#include <signal.h>
#include <time.h>
#include <pthread.h>
#include <limits.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>

#include "connectstuff.h"

/* FNAME_SIZE is 10 less than PATH_MAX to avoid warnings during snprintf */
#define FNAME_SIZE PATH_MAX - 10
static char sFnameToDelete[FNAME_SIZE];
static int sWatchdogTimeout = -1;
static size_t sWatchdogStrokeCount = 0;

static void *threadLooper(void *x)
{
    int runTime = 0;
    size_t lastStrokeSeen = sWatchdogStrokeCount;
    /* allow to run for up to 2 minutes */
    while (runTime < sWatchdogTimeout) {
        safeSleep(5);
        runTime += 5;
        if (lastStrokeSeen == sWatchdogStrokeCount) {
            msg("Watchdog not stroked for a while, printing stack: \n");
            printStackTrace();
        }
        lastStrokeSeen = sWatchdogStrokeCount;
    }
    msg("Watchdog about to abort with a timeout after %d\n", runTime);
    _exit(20);
    return NULL;
}


static void term_handler(int sig)
{
    msg("removing file: %s\n", sFnameToDelete);
    unlink(sFnameToDelete);
}

static void segv_handler(int sig)
{
    msg("SEGV detected!\n");
    printStackTrace();
    _exit(10);
}

void indicateConnectSucceeded(void)
{
    char fnameToCreate[PATH_MAX];
    FILE *fp;
    snprintf(fnameToCreate, PATH_MAX, "%s.done", sFnameToDelete);
    msg("Creating file: %s\n", fnameToCreate);
    fp = fopen(fnameToCreate, "wt");
    if (fp != NULL) {
        fclose(fp);
    }
}

void startWatchdog(int seconds)
{
    pthread_t theThread;
    sWatchdogTimeout = seconds;
    msg("Starting watchdog - timeout in %d\n", seconds);
    pthread_create(&theThread, NULL, threadLooper, NULL);
}

void strokeWatchdog()
{
    sWatchdogStrokeCount++;
}

void installSegvHandler(void)
{
    struct sigaction new_action;
    new_action.sa_handler = segv_handler;
    sigemptyset(&new_action.sa_mask);
    new_action.sa_flags = 0;
    sigaction(SIGSEGV, &new_action, NULL);
    msg("Installed SEGV handler\n");
}

void installExitHandler(const char *fname)
{
    /* Install signal handler */
    struct sigaction new_action;
    if (strlen(fname) > FNAME_SIZE) {
        msg("Fname: <%s> too long - aborting", fname);
        _exit(12);
    }
    strncpy(sFnameToDelete, fname, FNAME_SIZE);
    new_action.sa_handler = term_handler;
    sigemptyset(&new_action.sa_mask);
    new_action.sa_flags = 0;
    sigaction(SIGINT, &new_action, NULL);
    sigaction(SIGTERM, &new_action, NULL);
    msg("Installed signal handlers\n");
}