Diff options
-rw-r--r--source/cache.c3
-rwxr-xr-xtests/t0003-cache.sh15
2 files changed, 18 insertions, 0 deletions
diff --git a/source/cache.c b/source/cache.c
index 64b7148..004a84d 100644
--- a/source/cache.c
+++ b/source/cache.c
@@ -250,6 +250,9 @@ static int lock_slot(struct cache_slot *slot)
) {
err = errno;
fprintf(stderr, "[cgit] Unable to write %s: %s (%d)\n", slot->lock_path, strerror(err), err);
+ unlink(slot->lock_path);
+ close(slot->lock_fd);
+ slot->lock_fd = -1;
return err;
}
return 0;
diff --git a/tests/t0003-cache.sh b/tests/t0003-cache.sh
index 39f11a9..f4fa3cb 100755
--- a/tests/t0003-cache.sh
+++ b/tests/t0003-cache.sh
@@ -312,6 +312,21 @@ test_expect_success SANITY 'a refresh that cannot lock serves the expired slot a
grep "Unable to open .*\.lock: Permission denied" stale.err
'
+# A lock file that cannot take the key goes with its lock, rather than
+# staying behind locked while the page renders uncached. The limit is on
+# files, so the log goes through the pipe as well.
+test_expect_success 'a slot lock that cannot take its key is let go' '
+ rm -rf cache3 && mkdir cache3 &&
+ (
+ trap "" XFSZ &&
+ ulimit -f 0 &&
+ CGIT_CONFIG="$PWD/bigkeyrc" QUERY_STRING="url=bigpage/" cgit 2>&1
+ ) | cat >nokey.out &&
+ grep "</html>" nokey.out &&
+ grep "Unable to write .*\.lock" nokey.out &&
+ test_dir_is_empty cache3
+'
+
# A scan is cached in a file named after the hash of its path, so a first
# scan finds out what that name is. The index page is left uncached, which
# makes each request read the list afresh.