/
signal.c
86 lines (73 loc) · 1.75 KB
/
signal.c
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
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdatomic.h>
#include <pthread.h>
#include <errno.h>
static int signalled = 0;
static _Atomic int counter;
void sighandler(int signum) {
signalled = 1;
}
void delay(double d) {
struct timespec t;
int ret;
int loop = 0;
t.tv_sec = (time_t) d;
t.tv_nsec = (d - t.tv_sec) * 1e9;
do {
if (loop) {
putchar('x'); fflush(stdout);
}
ret = nanosleep(&t, &t);
loop++;
} while (ret == -1 && errno == EINTR && t.tv_sec < 5);
if (ret == -1) {
fprintf(stderr, " - nanosleep failed: %d, t = %lld, %lld\n", errno, t.tv_sec, t.tv_nsec);
exit(2);
}
}
void print_message(double d, char c) {
while (!signalled && atomic_load(&counter) <= 20) {
atomic_fetch_add(&counter, 1);
putchar(c);
fflush(stdout);
delay(d);
}
}
void * thread(void *arg) {
print_message(0.6666666666, 'a');
}
int main (void) {
struct sigaction sigact, oldsigact;
pthread_t thr;
pthread_attr_t attr;
pthread_cond_t done;
sigact.sa_handler = &sighandler;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = 0;
if (sigaction(SIGINT, &sigact, &oldsigact) == -1) {
fprintf(stderr, "Signal handler failed\n");
return 2;
}
atomic_init(&counter, 0);
if (pthread_cond_init(&done, NULL) != 0) {
fprintf(stderr, "Cond creation failed\n");
return 2;
}
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if (pthread_create(&thr, &attr, &thread, NULL) != 0) {
fprintf(stderr, "Thread creation failed\n");
return 2;
}
print_message(1.0, 'b');
pthread_join(thr, NULL);
if (signalled) {
printf(" - Got CTRL+C, exiting\n");
return 0;
} else {
printf(" - not signalled???\n");
return 2;
}
}