reftable/stack: refactor reloading to use file descriptor
We're about to introduce a stat(3P)-based caching mechanism to reload the list of stacks only when it has changed. In order to avoid race conditions this requires us to have a file descriptor available that we can use to call fstat(3P) on. Prepare for this by converting the code to use `fd_read_lines()` so that we have the file descriptor readily available. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Jan 11, 2024 at 11:06 UTC
c5b5d5fbbc43364a3d3c0aedf9e984a0ffe04537
1 file changed
+18
-3
reftable/stack.c
+18
-3
@@ -308,6 +308,7 @@ static int reftable_stack_reload_maybe_reuse(struct reftable_stack *st,
308
struct timeval deadline;
309
int64_t delay = 0;
310
int tries = 0, err;
311
+ int fd = -1;
312
313
err = gettimeofday(&deadline, NULL);
314
if (err < 0)
@@ -329,9 +330,19 @@ static int reftable_stack_reload_maybe_reuse(struct reftable_stack *st,
330
if (tries > 3 && tv_cmp(&now, &deadline) >= 0)
331
goto out;
332
332
- err = read_lines(st->list_file, &names);
333
- if (err < 0)
334
- goto out;
333
+ fd = open(st->list_file, O_RDONLY);
334
+ if (fd < 0) {
335
+ if (errno != ENOENT) {
336
+ err = REFTABLE_IO_ERROR;
337
+ goto out;
338
+ }
339
+
340
+ names = reftable_calloc(sizeof(char *));
341
+ } else {
342
+ err = fd_read_lines(fd, &names);
343
+ if (err < 0)
344
+ goto out;
345
+ }
346
347
err = reftable_stack_reload_once(st, names, reuse_open);
348
if (!err)
@@ -356,12 +367,16 @@ static int reftable_stack_reload_maybe_reuse(struct reftable_stack *st,
367
names = NULL;
368
free_names(names_after);
369
names_after = NULL;
370
+ close(fd);
371
+ fd = -1;
372
373
delay = delay + (delay * rand()) / RAND_MAX + 1;
374
sleep_millisec(delay);
375
}
376
377
out:
378
+ if (fd >= 0)
379
+ close(fd);
380
free_names(names);
381
free_names(names_after);
382
return err;