fsm-health-win32: add polling framework to monitor daemon health
Extend the Windows version of the "health" thread to periodically inspect the system and shutdown if warranted. This commit updates the thread's wait loop to use a timeout and defines a (currently empty) table of functions to poll the system. A later commit will add functions to the table to actually inspect the system. Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jeff Hostetler committed
May 26, 2022 at 21:47 UTC
90a70fa80964e7d582fb8df2c0115da79d13f5ab
1 file changed
+64
-1
compat/fsmonitor/fsm-health-win32.c
+64
-1
@@ -4,6 +4,24 @@
4
#include "fsm-health.h"
5
#include "fsmonitor--daemon.h"
6
7
+/*
8
+ * Every minute wake up and test our health.
9
+ */
10
+#define WAIT_FREQ_MS (60 * 1000)
11
+
12
+/*
13
+ * State machine states for each of the interval functions
14
+ * used for polling our health.
15
+ */
16
+enum interval_fn_ctx {
17
+ CTX_INIT = 0,
18
+ CTX_TERM,
19
+ CTX_TIMER
20
+};
21
+
22
+typedef int (interval_fn)(struct fsmonitor_daemon_state *state,
23
+ enum interval_fn_ctx ctx);
24
+
25
struct fsm_health_data
26
{
27
HANDLE hEventShutdown;
@@ -42,18 +60,61 @@ void fsm_health__dtor(struct fsmonitor_daemon_state *state)
60
FREE_AND_NULL(state->health_data);
61
}
62
63
+/*
64
+ * A table of the polling functions.
65
+ */
66
+static interval_fn *table[] = {
67
+ NULL, /* must be last */
68
+};
69
+
70
+/*
71
+ * Call all of the polling functions in the table.
72
+ * Shortcut and return first error.
73
+ *
74
+ * Return 0 if all succeeded.
75
+ */
76
+static int call_all(struct fsmonitor_daemon_state *state,
77
+ enum interval_fn_ctx ctx)
78
+{
79
+ int k;
80
+
81
+ for (k = 0; table[k]; k++) {
82
+ int r = table[k](state, ctx);
83
+ if (r)
84
+ return r;
85
+ }
86
+
87
+ return 0;
88
+}
89
+
90
void fsm_health__loop(struct fsmonitor_daemon_state *state)
91
{
92
struct fsm_health_data *data = state->health_data;
93
+ int r;
94
+
95
+ r = call_all(state, CTX_INIT);
96
+ if (r < 0)
97
+ goto force_error_stop;
98
+ if (r > 0)
99
+ goto force_shutdown;
100
101
for (;;) {
102
DWORD dwWait = WaitForMultipleObjects(data->nr_handles,
103
data->hHandles,
52
- FALSE, INFINITE);
104
+ FALSE, WAIT_FREQ_MS);
105
106
if (dwWait == WAIT_OBJECT_0 + HEALTH_SHUTDOWN)
107
goto clean_shutdown;
108
109
+ if (dwWait == WAIT_TIMEOUT) {
110
+ r = call_all(state, CTX_TIMER);
111
+ if (r < 0)
112
+ goto force_error_stop;
113
+ if (r > 0)
114
+ goto force_shutdown;
115
+ continue;
116
+ }
117
+
118
error(_("health thread wait failed [GLE %ld]"),
119
GetLastError());
120
goto force_error_stop;
@@ -61,8 +122,10 @@ void fsm_health__loop(struct fsmonitor_daemon_state *state)
122
123
force_error_stop:
124
state->health_error_code = -1;
125
+force_shutdown:
126
ipc_server_stop_async(state->ipc_server_data);
127
clean_shutdown:
128
+ call_all(state, CTX_TERM);
129
return;
130
}
131