Diff options
authorBryce Kwon <bryce@brycekwon.com>
committerBryce Kwon <bryce@brycekwon.com>
commit
parent
tree
download
Share one lock-file helper between the caches
Diffstat (limited to 'source/cgit.c')
-rw-r--r--source/cgit.c38
1 file changed, 3 insertions, 35 deletions
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 <sys/file.h>
// 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);