Skip to content

Commit ee4d8e4

Browse files
peffgitster
authored andcommitted
ref_lock: stop leaking lock_files
Since the tempfile code recently relaxed the rule that tempfile structs (and thus locks) need to hang around forever, we no longer have to leak our lock_file structs. In fact, we don't even need to heap-allocate them anymore, since their lifetime can just match that of the surrounding ref_lock (and if we forget to delete a lock, the effect is the same as before: it will eventually go away at program exit). Note that there is a check in unlock_ref() to only rollback a lock file if it has been allocated. We don't need that check anymore; we zero the ref_lock (and thus the lock_file), so at worst we pass a NULL pointer to delete_tempfile(), which considers that a noop. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 5e7f01c commit ee4d8e4

1 file changed

Lines changed: 16 additions & 23 deletions

File tree

refs/files-backend.c

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
struct ref_lock {
1414
char *ref_name;
15-
struct lock_file *lk;
15+
struct lock_file lk;
1616
struct object_id old_oid;
1717
};
1818

@@ -418,9 +418,7 @@ static int files_read_raw_ref(struct ref_store *ref_store,
418418

419419
static void unlock_ref(struct ref_lock *lock)
420420
{
421-
/* Do not free lock->lk -- atexit() still looks at them */
422-
if (lock->lk)
423-
rollback_lock_file(lock->lk);
421+
rollback_lock_file(&lock->lk);
424422
free(lock->ref_name);
425423
free(lock);
426424
}
@@ -534,11 +532,8 @@ static int lock_raw_ref(struct files_ref_store *refs,
534532
goto error_return;
535533
}
536534

537-
if (!lock->lk)
538-
lock->lk = xcalloc(1, sizeof(struct lock_file));
539-
540535
if (hold_lock_file_for_update_timeout(
541-
lock->lk, ref_file.buf, LOCK_NO_DEREF,
536+
&lock->lk, ref_file.buf, LOCK_NO_DEREF,
542537
get_files_ref_lock_timeout_ms()) < 0) {
543538
if (errno == ENOENT && --attempts_remaining > 0) {
544539
/*
@@ -949,11 +944,9 @@ static struct ref_lock *lock_ref_sha1_basic(struct files_ref_store *refs,
949944
goto error_return;
950945
}
951946

952-
lock->lk = xcalloc(1, sizeof(struct lock_file));
953-
954947
lock->ref_name = xstrdup(refname);
955948

956-
if (raceproof_create_file(ref_file.buf, create_reflock, lock->lk)) {
949+
if (raceproof_create_file(ref_file.buf, create_reflock, &lock->lk)) {
957950
last_errno = errno;
958951
unable_to_lock_message(ref_file.buf, errno, err);
959952
goto error_return;
@@ -1404,14 +1397,14 @@ static int files_rename_ref(struct ref_store *ref_store,
14041397

14051398
static int close_ref_gently(struct ref_lock *lock)
14061399
{
1407-
if (close_lock_file_gently(lock->lk))
1400+
if (close_lock_file_gently(&lock->lk))
14081401
return -1;
14091402
return 0;
14101403
}
14111404

14121405
static int commit_ref(struct ref_lock *lock)
14131406
{
1414-
char *path = get_locked_file_path(lock->lk);
1407+
char *path = get_locked_file_path(&lock->lk);
14151408
struct stat st;
14161409

14171410
if (!lstat(path, &st) && S_ISDIR(st.st_mode)) {
@@ -1435,7 +1428,7 @@ static int commit_ref(struct ref_lock *lock)
14351428
free(path);
14361429
}
14371430

1438-
if (commit_lock_file(lock->lk))
1431+
if (commit_lock_file(&lock->lk))
14391432
return -1;
14401433
return 0;
14411434
}
@@ -1627,12 +1620,12 @@ static int write_ref_to_lockfile(struct ref_lock *lock,
16271620
unlock_ref(lock);
16281621
return -1;
16291622
}
1630-
fd = get_lock_file_fd(lock->lk);
1623+
fd = get_lock_file_fd(&lock->lk);
16311624
if (write_in_full(fd, oid_to_hex(oid), GIT_SHA1_HEXSZ) != GIT_SHA1_HEXSZ ||
16321625
write_in_full(fd, &term, 1) != 1 ||
16331626
close_ref_gently(lock) < 0) {
16341627
strbuf_addf(err,
1635-
"couldn't write '%s'", get_lock_file_path(lock->lk));
1628+
"couldn't write '%s'", get_lock_file_path(&lock->lk));
16361629
unlock_ref(lock);
16371630
return -1;
16381631
}
@@ -1709,7 +1702,7 @@ static int create_ref_symlink(struct ref_lock *lock, const char *target)
17091702
{
17101703
int ret = -1;
17111704
#ifndef NO_SYMLINK_HEAD
1712-
char *ref_path = get_locked_file_path(lock->lk);
1705+
char *ref_path = get_locked_file_path(&lock->lk);
17131706
unlink(ref_path);
17141707
ret = symlink(target, ref_path);
17151708
free(ref_path);
@@ -1745,14 +1738,14 @@ static int create_symref_locked(struct files_ref_store *refs,
17451738
return 0;
17461739
}
17471740

1748-
if (!fdopen_lock_file(lock->lk, "w"))
1741+
if (!fdopen_lock_file(&lock->lk, "w"))
17491742
return error("unable to fdopen %s: %s",
1750-
lock->lk->tempfile->filename.buf, strerror(errno));
1743+
lock->lk.tempfile->filename.buf, strerror(errno));
17511744

17521745
update_symref_reflog(refs, lock, refname, target, logmsg);
17531746

17541747
/* no error check; commit_ref will check ferror */
1755-
fprintf(lock->lk->tempfile->fp, "ref: %s\n", target);
1748+
fprintf(lock->lk.tempfile->fp, "ref: %s\n", target);
17561749
if (commit_ref(lock) < 0)
17571750
return error("unable to write symref for %s: %s", refname,
17581751
strerror(errno));
@@ -2853,12 +2846,12 @@ static int files_reflog_expire(struct ref_store *ref_store,
28532846
strerror(errno));
28542847
rollback_lock_file(&reflog_lock);
28552848
} else if (update &&
2856-
(write_in_full(get_lock_file_fd(lock->lk),
2849+
(write_in_full(get_lock_file_fd(&lock->lk),
28572850
oid_to_hex(&cb.last_kept_oid), GIT_SHA1_HEXSZ) != GIT_SHA1_HEXSZ ||
2858-
write_str_in_full(get_lock_file_fd(lock->lk), "\n") != 1 ||
2851+
write_str_in_full(get_lock_file_fd(&lock->lk), "\n") != 1 ||
28592852
close_ref_gently(lock) < 0)) {
28602853
status |= error("couldn't write %s",
2861-
get_lock_file_path(lock->lk));
2854+
get_lock_file_path(&lock->lk));
28622855
rollback_lock_file(&reflog_lock);
28632856
} else if (commit_lock_file(&reflog_lock)) {
28642857
status |= error("unable to write reflog '%s' (%s)",

0 commit comments

Comments
 (0)