git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Michael Haggerty <mhagger@alum.mit.edu>
To: Junio C Hamano <gitster@pobox.com>
Cc: Johannes Sixt <j6t@kdbg.org>, git@vger.kernel.org
Subject: Re: [PATCH v2 12/16] diff: use tempfile module
Date: Wed, 12 Aug 2015 17:13:59 +0200	[thread overview]
Message-ID: <55CB62B7.8060706@alum.mit.edu> (raw)
In-Reply-To: <xmqqbnedr3sp.fsf@gitster.dls.corp.google.com>

On 08/11/2015 10:03 PM, Junio C Hamano wrote:
> Michael Haggerty <mhagger@alum.mit.edu> writes:
> 
>> Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
>> ---
>>  diff.c | 29 +++++++----------------------
>>  1 file changed, 7 insertions(+), 22 deletions(-)
> 
> Nice code reduction.
> 
>> diff --git a/diff.c b/diff.c
>> index 7500c55..dc95247 100644
>> --- a/diff.c
>> +++ b/diff.c
>> @@ -2,6 +2,7 @@
>>   * Copyright (C) 2005 Junio C Hamano
>>   */
>>  #include "cache.h"
>> +#include "tempfile.h"
>>  #include "quote.h"
>>  #include "diff.h"
>>  #include "diffcore.h"
>> @@ -312,7 +313,7 @@ static struct diff_tempfile {
>>  	const char *name; /* filename external diff should read from */
>>  	char hex[41];
>>  	char mode[10];
>> -	char tmp_path[PATH_MAX];
>> +	struct tempfile tempfile;
>>  } diff_temp[2];
>>  
>>  typedef unsigned long (*sane_truncate_fn)(char *line, unsigned long len);
>> @@ -564,25 +565,16 @@ static struct diff_tempfile *claim_diff_tempfile(void) {
>>  	die("BUG: diff is failing to clean up its tempfiles");
>>  }
>>  
>> -static int remove_tempfile_installed;
>> -
>>  static void remove_tempfile(void)
>>  {
>>  	int i;
>>  	for (i = 0; i < ARRAY_SIZE(diff_temp); i++) {
>> -		if (diff_temp[i].name == diff_temp[i].tmp_path)
>> -			unlink_or_warn(diff_temp[i].name);
>> +		if (is_tempfile_active(&diff_temp[i].tempfile))
>> +			delete_tempfile(&diff_temp[i].tempfile);
> 
> I suspect that this indicates that there is something iffy in the
> conversion.  The original invariant, that is consistently used
> between claim_diff_tempfile() and remove_tempfile(), is that .name
> field points at .tmp_path for a slot in diff_temp[] that holds a
> temporary that is in use.  Otherwise, .name is NULL and it can be
> claimed for your own use.

No, prepare_temp_file() sometimes sets diff_tempfile::name to
"/dev/null", and sometimes to point at its argument `name`. In either of
these cases .tmp_path can hold anything, and the file is *not* cleaned
up even though the diff_temp entry is considered by
claim_diff_tempfile() to be in use.

If I'm not mistaken, the old invariant was:

* Iff diff_tempfile::name is NULL, the entry is not in use.
* Iff diff_tempfile::name == diff_tempfile::tmp_path, then the entry is
in use and refers to a temporary file that needs to be cleaned up.
* Otherwise, the entry is in use but the corresponding file should *not*
be cleaned up.

The new invariant is:

* Iff diff_tempfile::name is NULL, the entry is not in use. In these
cases, is_tempfile_active() is always false.
* Iff is_tempfile_active(diff_tempfile::tempfile), then it refers to a
file that needs to get cleaned up. In these cases name points at the
tempfile object's filename.
* If neither of the above is true, then the entry is in use but the
corresponding file should not be cleaned up.

> Here the updated code uses a different and new invariant: .tempfile
> satisfies is_tempfile_active() for a slot in use.  But the check in
> claim_diff_tempfile() still relies on the original invariant.

That is not true. The is_tempfile_active() check is only used in
remove_tempfile() when deciding whether to clean up the file. The check
in claim_diff_tempfile() wants to know whether the entry is in use, so
it uses the other check.

> The updated code may happen to always have an active tempfile in
> tempfile and always set NULL when it clears .name, but that would
> mean (1) future changes may easily violate one of invariants (we
> used to have only one, now we have two that have to be sync) by
> mistake, and (2) we are keeping track of two closely linked things
> as two invariants.
> 
> As the value that used to be in the .name field can now be obtained
> by calling get_tempfile_path() on the .tempfile field, perhaps we
> should drop .name (and its associated invariant) at the same time?

This is also incorrect. See my first paragraph above.

I will change this patch to document the invariants.

Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu

  reply	other threads:[~2015-08-12 15:14 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-10  9:47 [PATCH v2 00/16] Introduce a tempfile module Michael Haggerty
2015-08-10  9:47 ` [PATCH v2 01/16] Move lockfile documentation to lockfile.h and lockfile.c Michael Haggerty
2015-08-11 19:27   ` Junio C Hamano
2015-08-10  9:47 ` [PATCH v2 02/16] create_bundle(): duplicate file descriptor to avoid closing it twice Michael Haggerty
2015-08-10  9:47 ` [PATCH v2 03/16] lockfile: add accessors get_lock_file_fd() and get_lock_file_fp() Michael Haggerty
2015-08-11 19:29   ` Junio C Hamano
2015-08-10  9:47 ` [PATCH v2 04/16] lockfile: add accessor get_lock_file_path() Michael Haggerty
2015-08-11 19:36   ` Junio C Hamano
2015-08-10  9:47 ` [PATCH v2 05/16] commit_lock_file(): use get_locked_file_path() Michael Haggerty
2015-08-10  9:47 ` [PATCH v2 06/16] tempfile: a new module for handling temporary files Michael Haggerty
2015-08-10  9:47 ` [PATCH v2 07/16] prepare_tempfile_object(): new function, extracted from create_tempfile() Michael Haggerty
2015-08-11 19:38   ` Junio C Hamano
2015-08-10  9:47 ` [PATCH v2 08/16] tempfile: add several functions for creating temporary files Michael Haggerty
2015-08-10  9:47 ` [PATCH v2 09/16] register_tempfile(): new function to handle an existing temporary file Michael Haggerty
2015-08-10  9:47 ` [PATCH v2 10/16] write_shared_index(): use tempfile module Michael Haggerty
2015-08-10  9:47 ` [PATCH v2 11/16] setup_temporary_shallow(): " Michael Haggerty
2015-08-10  9:47 ` [PATCH v2 12/16] diff: " Michael Haggerty
2015-08-11 20:03   ` Junio C Hamano
2015-08-12 15:13     ` Michael Haggerty [this message]
2015-08-12 16:41       ` Junio C Hamano
2015-08-12 17:12         ` [PATCH v2' " Michael Haggerty
2015-08-10  9:47 ` [PATCH v2 13/16] lock_repo_for_gc(): compute the path to "gc.pid" only once Michael Haggerty
2015-08-11 20:06   ` Junio C Hamano
2015-08-11 20:20     ` Junio C Hamano
2015-08-10  9:47 ` [PATCH v2 14/16] gc: use tempfile module to handle gc.pid file Michael Haggerty
2015-08-10  9:47 ` [PATCH v2 15/16] credential-cache--daemon: delete socket from main() Michael Haggerty
2015-08-10  9:47 ` [PATCH v2 16/16] credential-cache--daemon: use tempfile module Michael Haggerty
2015-08-11 20:21 ` [PATCH v2 00/16] Introduce a " Junio C Hamano
2015-08-12 15:14   ` Michael Haggerty

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=55CB62B7.8060706@alum.mit.edu \
    --to=mhagger@alum.mit.edu \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=j6t@kdbg.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).