From bf4cd88262afbfcdae29266b51adc5f35901d09c Mon Sep 17 00:00:00 2001 From: Bryce Kwon Date: Sat, 31 Oct 2026 14:48:03 -0700 Subject: Share one lock-file helper between the caches --- source/cgit.c | 38 +++----------------------------------- 1 file changed, 3 insertions(+), 35 deletions(-) (limited to 'source/cgit.c') diff --git a/source/cgit.c b/source/cgit.c index bccc58f..245e77d 100644 --- a/source/cgit.c +++ b/source/cgit.c @@ -27,7 +27,6 @@ #include "ui-shared.h" #include "ui-snapshot.h" #include "ui-stats.h" -#include // Deliberately small. The whole body is read at once and handed to the auth // filter, so a filter never has to defend itself against a huge or a @@ -329,47 +328,16 @@ static void parse_args(int argc, const char **argv) static int generate_cached_repolist(const char *path, const char *cached_rc) { struct strbuf locked_rc = STRBUF_INIT; - struct stat held, named; int err = 0; int fd; int first; FILE *f; strbuf_addf(&locked_rc, "%s.lock", cached_rc); - fd = open(locked_rc.buf, O_RDWR | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR); - if (fd == -1) { - err = errno; - fprintf(stderr, "[cgit] Unable to open %s: %s (%d)\n", locked_rc.buf, strerror(err), err); - goto out; - } - if (flock(fd, LOCK_EX | LOCK_NB) < 0) { - // A lock held elsewhere only means concurrent requests, which - // is not worth a line in the server log. Any other failure, a - // filesystem without lock support say, silently costs a scan - // on every request and does deserve one. - err = errno; - if (err != EWOULDBLOCK) - fprintf(stderr, "[cgit] Unable to lock %s: %s (%d)\n", locked_rc.buf, strerror(err), err); - close(fd); + err = cache_lock_file(locked_rc.buf, &fd); + if (err) goto out; - } - // The lock landed on whatever inode the path named at open. A holder - // finishing in between renames that inode into place as the live - // list, and once the path is confirmed to still name this file that - // rename can no longer happen, because it takes the lock held here. - if ( - fstat(fd, &held) || - stat(locked_rc.buf, &named) || - held.st_ino != named.st_ino || - held.st_dev != named.st_dev - ) { - err = EAGAIN; - close(fd); - goto out; - } - // A run that died before its rename leaves the lock file behind, so - // start from empty now that nobody else can be writing it. - if (ftruncate(fd, 0) < 0 || !(f = fdopen(fd, "w"))) { + if (!(f = fdopen(fd, "w"))) { err = errno; fprintf(stderr, "[cgit] Unable to write %s: %s (%d)\n", locked_rc.buf, strerror(err), err); unlink(locked_rc.buf); -- cgit