netlink: Provide MDEBUG macro
[secnet] / hackypar.c
CommitLineData
3b83c932
SE
1/* Hacky parallelism; Ian Jackson */
2
3#define _GNU_SOURCE
4
5#include "secnet.h"
6#include "util.h"
7#include "hackypar.h"
8
9#ifdef HACKY_PARALLEL
10
11#include <stdio.h>
12#include <unistd.h>
13#include <errno.h>
14#include <string.h>
15#include <signal.h>
16#include <assert.h>
17#include <sys/wait.h>
18
19#define HASHSIZE 16
20#define CACHESIZE 16
21
22typedef enum { hp_idle, hp_compute, hp_deferring, hp_fail } HPState;
23
24static HPState state;
25static pid_t child;
26
27static void checkchild(void) {
28 int r, status;
29
30 if (!child) return;
31
32 r= waitpid(child,&status,WNOHANG); if (!r) return;
33 if (r==-1) {
34 Message(M_ERR,"hacky_par: waitpid: %s\n",strerror(errno));
35 return;
36 }
37 child= 0;
38
39 if (WIFSIGNALED(status)) {
40 Message(M_ERR,"hacky_par: signaled! %s\n",strsignal(WTERMSIG(status)));
41 } else if (!WIFEXITED(status)) {
42 Message(M_ERR,"hacky_par: unexpected status! %d\n", r);
43 }
44}
45
46static HPState start(void) {
47 assert(!child);
48
49 child= fork();
50 if (child == -1) {
51 Message(M_ERR,"hacky_par: fork failed: %s\n",strerror(errno));
52 return hp_fail;
53 }
54
55 if (!child) { /* we are the child */
56 return hp_compute;
57 }
58
59 Message(M_INFO,"hacky_par: started, punting\n");
60 return hp_deferring;
61}
62
63int hacky_par_start_failnow(void) {
64 state= hp_idle;
65 checkchild();
66 if (child) {
67 state= hp_deferring;
68 Message(M_INFO,"hacky_par: busy, punting\n");
69 return 1;
70 }
71 return 0;
72}
73
74int hacky_par_mid_failnow(void) {
75 state= start();
76 return state != hp_compute;
77}
78
79bool_t (*packy_par_gen)(struct site *st);
80
81void hacky_par_end(int *ok,
4a8aed08 82 int32_t retries, int32_t timeout,
3b83c932
SE
83 bool_t (*send_msg)(struct site *st), struct site *st) {
84 int i;
85
86 switch (state) {
87 case hp_deferring:
88 assert(!*ok);
89 *ok= 1;
90 return;
91 case hp_fail:
92 assert(!*ok);
93 return;
94 case hp_idle:
95 return;
96 case hp_compute:
97 if (!ok) {
98 Message(M_ERR,"hacky_par: compute failed\n");
99 _exit(2);
100 }
101 Message(M_INFO,"hacky_par: got result, sending\n");
102 for (i=1; i<retries; i++) {
103 sleep((timeout + 999)/1000);
104 if (!send_msg(st)) {
105 Message(M_ERR,"hacky_par: retry failed\n");
106 _exit(1);
107 }
108 }
109 _exit(0);
110 }
111}
112
113#else /*!HACKY_PARALLEL*/
114
115int hacky_par_start_failnow(void) { return 0; }
116int hacky_par_mid_failnow(void) { return 0; }
117void hacky_par_end(int *ok,
4a8aed08 118 int32_t retries, int32_t timeout,
3b83c932
SE
119 bool_t (*send_msg)(struct site *st), struct site *st) { }
120
121#endif /*HACKY_PARALLEL...else*/