Skip to content

Commit 90a70fa

Browse files
jeffhostetlergitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent d060555 commit 90a70fa

File tree

1 file changed

+64
-1
lines changed

1 file changed

+64
-1
lines changed

compat/fsmonitor/fsm-health-win32.c

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,24 @@
44
#include "fsm-health.h"
55
#include "fsmonitor--daemon.h"
66

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+
725
struct fsm_health_data
826
{
927
HANDLE hEventShutdown;
@@ -42,27 +60,72 @@ void fsm_health__dtor(struct fsmonitor_daemon_state *state)
4260
FREE_AND_NULL(state->health_data);
4361
}
4462

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+
4590
void fsm_health__loop(struct fsmonitor_daemon_state *state)
4691
{
4792
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;
48100

49101
for (;;) {
50102
DWORD dwWait = WaitForMultipleObjects(data->nr_handles,
51103
data->hHandles,
52-
FALSE, INFINITE);
104+
FALSE, WAIT_FREQ_MS);
53105

54106
if (dwWait == WAIT_OBJECT_0 + HEALTH_SHUTDOWN)
55107
goto clean_shutdown;
56108

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+
57118
error(_("health thread wait failed [GLE %ld]"),
58119
GetLastError());
59120
goto force_error_stop;
60121
}
61122

62123
force_error_stop:
63124
state->health_error_code = -1;
125+
force_shutdown:
64126
ipc_server_stop_async(state->ipc_server_data);
65127
clean_shutdown:
128+
call_all(state, CTX_TERM);
66129
return;
67130
}
68131

0 commit comments

Comments
 (0)