fsmonitor: refactor initialization of fsmonitor_last_update token
Isolate and document initialization of `istate->fsmonitor_last_update`. This field should contain a fsmonitor-specific opaque token, but we need to initialize it before we can actually talk to a fsmonitor process, so we create a generic default value. Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com> Reviewed-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jeff Hostetler committed
Feb 3, 2021 at 15:34 UTC
fcd19b09f8b2cddffe18dc4d2f974fce94dc27b0
1 file changed
+32
-3
fsmonitor.c
+32
-3
@@ -343,16 +343,45 @@ void refresh_fsmonitor(struct index_state *istate)
343
istate->fsmonitor_last_update = strbuf_detach(&last_update_token, NULL);
344
}
345
346
+/*
347
+ * The caller wants to turn on FSMonitor. And when the caller writes
348
+ * the index to disk, a FSMonitor extension should be included. This
349
+ * requires that `istate->fsmonitor_last_update` not be NULL. But we
350
+ * have not actually talked to a FSMonitor process yet, so we don't
351
+ * have an initial value for this field.
352
+ *
353
+ * For a protocol V1 FSMonitor process, this field is a formatted
354
+ * "nanoseconds since epoch" field. However, for a protocol V2
355
+ * FSMonitor process, this field is an opaque token.
356
+ *
357
+ * Historically, `add_fsmonitor()` has initialized this field to the
358
+ * current time for protocol V1 processes. There are lots of race
359
+ * conditions here, but that code has shipped...
360
+ *
361
+ * The only true solution is to use a V2 FSMonitor and get a current
362
+ * or default token value (that it understands), but we cannot do that
363
+ * until we have actually talked to an instance of the FSMonitor process
364
+ * (but the protocol requires that we send a token first...).
365
+ *
366
+ * For simplicity, just initialize like we have a V1 process and require
367
+ * that V2 processes adapt.
368
+ */
369
+static void initialize_fsmonitor_last_update(struct index_state *istate)
370
+{
371
+ struct strbuf last_update = STRBUF_INIT;
372
+
373
+ strbuf_addf(&last_update, "%"PRIu64"", getnanotime());
374
+ istate->fsmonitor_last_update = strbuf_detach(&last_update, NULL);
375
+}
376
+
377
void add_fsmonitor(struct index_state *istate)
378
{
379
unsigned int i;
349
- struct strbuf last_update = STRBUF_INIT;
380
381
if (!istate->fsmonitor_last_update) {
382
trace_printf_key(&trace_fsmonitor, "add fsmonitor");
383
istate->cache_changed |= FSMONITOR_CHANGED;
354
- strbuf_addf(&last_update, "%"PRIu64"", getnanotime());
355
- istate->fsmonitor_last_update = strbuf_detach(&last_update, NULL);
384
+ initialize_fsmonitor_last_update(istate);
385
386
/* reset the fsmonitor state */
387
for (i = 0; i < istate->cache_nr; i++)