summaryrefslogtreecommitdiff
path: root/compat
diff options
context:
space:
mode:
authorJeff Hostetler <jeffhost@microsoft.com>2022-05-26 21:47:11 (GMT)
committerJunio C Hamano <gitster@pobox.com>2022-05-26 22:59:27 (GMT)
commit90a70fa80964e7d582fb8df2c0115da79d13f5ab (patch)
tree561b209bac999ac667accc9baccfff7aa0b891c4 /compat
parentd06055501b0d31c417f8cbd237efb48065256d83 (diff)
downloadgit-90a70fa80964e7d582fb8df2c0115da79d13f5ab.zip
git-90a70fa80964e7d582fb8df2c0115da79d13f5ab.tar.gz
git-90a70fa80964e7d582fb8df2c0115da79d13f5ab.tar.bz2
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>
Diffstat (limited to 'compat')
-rw-r--r--compat/fsmonitor/fsm-health-win32.c65
1 files changed, 64 insertions, 1 deletions
diff --git a/compat/fsmonitor/fsm-health-win32.c b/compat/fsmonitor/fsm-health-win32.c
index 94b1d02..24fc612 100644
--- a/compat/fsmonitor/fsm-health-win32.c
+++ b/compat/fsmonitor/fsm-health-win32.c
@@ -4,6 +4,24 @@
#include "fsm-health.h"
#include "fsmonitor--daemon.h"
+/*
+ * Every minute wake up and test our health.
+ */
+#define WAIT_FREQ_MS (60 * 1000)
+
+/*
+ * State machine states for each of the interval functions
+ * used for polling our health.
+ */
+enum interval_fn_ctx {
+ CTX_INIT = 0,
+ CTX_TERM,
+ CTX_TIMER
+};
+
+typedef int (interval_fn)(struct fsmonitor_daemon_state *state,
+ enum interval_fn_ctx ctx);
+
struct fsm_health_data
{
HANDLE hEventShutdown;
@@ -42,18 +60,61 @@ void fsm_health__dtor(struct fsmonitor_daemon_state *state)
FREE_AND_NULL(state->health_data);
}
+/*
+ * A table of the polling functions.
+ */
+static interval_fn *table[] = {
+ NULL, /* must be last */
+};
+
+/*
+ * Call all of the polling functions in the table.
+ * Shortcut and return first error.
+ *
+ * Return 0 if all succeeded.
+ */
+static int call_all(struct fsmonitor_daemon_state *state,
+ enum interval_fn_ctx ctx)
+{
+ int k;
+
+ for (k = 0; table[k]; k++) {
+ int r = table[k](state, ctx);
+ if (r)
+ return r;
+ }
+
+ return 0;
+}
+
void fsm_health__loop(struct fsmonitor_daemon_state *state)
{
struct fsm_health_data *data = state->health_data;
+ int r;
+
+ r = call_all(state, CTX_INIT);
+ if (r < 0)
+ goto force_error_stop;
+ if (r > 0)
+ goto force_shutdown;
for (;;) {
DWORD dwWait = WaitForMultipleObjects(data->nr_handles,
data->hHandles,
- FALSE, INFINITE);
+ FALSE, WAIT_FREQ_MS);
if (dwWait == WAIT_OBJECT_0 + HEALTH_SHUTDOWN)
goto clean_shutdown;
+ if (dwWait == WAIT_TIMEOUT) {
+ r = call_all(state, CTX_TIMER);
+ if (r < 0)
+ goto force_error_stop;
+ if (r > 0)
+ goto force_shutdown;
+ continue;
+ }
+
error(_("health thread wait failed [GLE %ld]"),
GetLastError());
goto force_error_stop;
@@ -61,8 +122,10 @@ void fsm_health__loop(struct fsmonitor_daemon_state *state)
force_error_stop:
state->health_error_code = -1;
+force_shutdown:
ipc_server_stop_async(state->ipc_server_data);
clean_shutdown:
+ call_all(state, CTX_TERM);
return;
}