All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Cc: git@vger.kernel.org, "Junio C Hamano" <gitster@pobox.com>,
	"Michał Kępień" <michal@isc.org>,
	"Phillip Wood" <phillip.wood123@gmail.com>
Subject: Re: [PATCH 1/2] diff: add an API for deferred freeing
Date: Thu, 11 Feb 2021 04:00:31 +0100	[thread overview]
Message-ID: <878s7vcnqo.fsf@evledraar.gmail.com> (raw)
In-Reply-To: <nycvar.QRO.7.76.6.2102101557160.29765@tvgsbejvaqbjf.bet>


On Wed, Feb 10 2021, Johannes Schindelin wrote:

> Hi Ævar,
>
> On Fri, 5 Feb 2021, Ævar Arnfjörð Bjarmason wrote:
>
>> Add a diff_free() function to free anything we may have allocated in
>> the "diff_options" struct, and the ability to make calling it a noop
>> by setting "no_free" in "diff_options".
>
> Why do we need a `no_free` flag? Why not simply set the `free()`d (or
> `fclose()`d) attributes to `NULL`?

Because we're calling the diff API N times, so we need to not have those
be NULL while we're using them in a loop, and we need to not free()
them, and then flip "no_free = 0" at the end and free() them.

>> diff --git a/builtin/add.c b/builtin/add.c
>> index a825887c50..6319710186 100644
>> --- a/builtin/add.c
>> +++ b/builtin/add.c
>> @@ -282,7 +282,7 @@ static int edit_patch(int argc, const char **argv, const char *prefix)
>>  	if (out < 0)
>>  		die(_("Could not open '%s' for writing."), file);
>>  	rev.diffopt.file = xfdopen(out, "w");
>> -	rev.diffopt.close_file = 1;
>> +	rev.diffopt.fclose_file = 1;
>
> This rename makes the patch unnecessarily tedious to review, and I do not
> even agree with leaking the implementation detail that we need to
> `fclose()` the file.
>
> Let's just not?

Fair enough, I figured it would be easier for reviewers to reason about
to be guaranteed to see all the uses of the flag, but I'll drop it.

>> @@ -6399,10 +6399,10 @@ void diff_flush(struct diff_options *options)
>>  		 * options->file to /dev/null should be safe, because we
>>  		 * aren't supposed to produce any output anyway.
>>  		 */
>> -		if (options->close_file)
>> +		if (options->fclose_file)
>>  			fclose(options->file);
>
> And at this stage, we should set `options->file = NULL`.

Sure, why not, but unless we get rid of the need for "close_file"
there's not much point other than ease of inspection in a
debugger...[cont].

>> [...]
>> +void diff_free(struct diff_options *options)
>> +{
>> +	if (options->no_free)
>> +		return;
>> +	if (options->fclose_file)
>> +		fclose(options->file);
>
> And at this stage, we should set `options->file = NULL`.

...ditto...[cont]

>> +}
>> +
>> +
>>  static int match_filter(const struct diff_options *options, const struct diff_filepair *p)
>>  {
>>  	return (((p->status == DIFF_STATUS_MODIFIED) &&
>> diff --git a/diff.h b/diff.h
>> index 2ff2b1c7f2..d1d74c3a9e 100644
>> --- a/diff.h
>> +++ b/diff.h
>> @@ -49,7 +49,16 @@
>>   * - Once you finish feeding the pairs of files, call `diffcore_std()`.
>>   * This will tell the diffcore library to go ahead and do its work.
>>   *
>> + * - The `diff_opt_parse()` etc. functions might allocate memory in
>> + *  `struct diff_options`. When running the API `N > 1` set `.no_free
>> + *  = 1` to make the `diff_free()` invoked by `diff_flush()` below a
>> + *  noop.
>
> I have serious trouble parsing that last sentence. Would you mind
> rephrasing it?

Willdo.

>> + *
>>   * - Calling `diff_flush()` will produce the output.
>> + *
>> + * - If you set `.no_free = 1` before set it to `0` and call
>> + *   `diff_free()` again. If `.no_free = 1` was not set there's no
>> + *   need to call `diff_free()`, `diff_flush()` will call it.
>
> Again, as I mentioned before, the indicator whether things need to be
> released should be whether the attribute is `NULL` or not. And once
> released, ot should be set to `NULL`.
>
> Other than that, it looks fine to me. And I definitely like the idea of
> introducing a function to release all of the stuff in `struct diffopt`.

[cont]...I don't think it's possible in anything like the current API to
do that.

We don't want to "if (file) fclose(file)", instead we need an opt-in "if
(close_file) fclose(file)". That's because usually the "file" is
stdout. So close_file=1 is only set when we're opening a "real" file,
/dev/null or whatever.

That along with the "no_free" flag as noted above means we need both a
"no_free" and "close_file" flags.

Unless there's some way of re-arranging this that I'm missing.

  reply	other threads:[~2021-02-11  3:01 UTC|newest]

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-01 12:06 [PATCH 0/2] diff: add -I<regex> that ignores matching changes Michał Kępień
2020-10-01 12:06 ` [PATCH 1/2] " Michał Kępień
2020-10-01 18:21   ` Junio C Hamano
2020-10-07 19:48     ` Michał Kępień
2020-10-07 20:08       ` Junio C Hamano
2020-10-01 12:06 ` [PATCH 2/2] t: add -I<regex> tests Michał Kępień
2020-10-01 17:02 ` [PATCH 0/2] diff: add -I<regex> that ignores matching changes Junio C Hamano
2020-10-12  9:17 ` [PATCH v2 0/3] " Michał Kępień
2020-10-12  9:17   ` [PATCH v2 1/3] merge-base, xdiff: zero out xpparam_t structures Michał Kępień
2020-10-12 11:14     ` Johannes Schindelin
2020-10-12 17:09       ` Junio C Hamano
2020-10-12 19:52     ` Junio C Hamano
2020-10-13  6:35       ` Michał Kępień
2020-10-12  9:17   ` [PATCH v2 2/3] diff: add -I<regex> that ignores matching changes Michał Kępień
2020-10-12 11:20     ` Johannes Schindelin
2020-10-12 20:00       ` Junio C Hamano
2020-10-12 20:39         ` Johannes Schindelin
2020-10-12 21:43           ` Junio C Hamano
2020-10-13  6:37             ` Michał Kępień
2020-10-13 15:49               ` Junio C Hamano
2020-10-13  6:36       ` Michał Kępień
2020-10-13 12:02         ` Johannes Schindelin
2020-10-13 15:53           ` Junio C Hamano
2020-10-13 18:45           ` Michał Kępień
2020-10-12 18:01     ` Junio C Hamano
2020-10-13  6:38       ` Michał Kępień
2020-10-12 20:04     ` Junio C Hamano
2020-10-13  6:38       ` Michał Kępień
2020-10-12  9:17   ` [PATCH v2 3/3] t: add -I<regex> tests Michał Kępień
2020-10-12 11:49     ` Johannes Schindelin
2020-10-13  6:38       ` Michał Kępień
2020-10-13 12:00         ` Johannes Schindelin
2020-10-13 16:00           ` Junio C Hamano
2020-10-13 19:01           ` Michał Kępień
2020-10-15 11:45             ` Johannes Schindelin
2020-10-15  7:24   ` [PATCH v3 0/2] diff: add -I<regex> that ignores matching changes Michał Kępień
2020-10-15  7:24     ` [PATCH v3 1/2] merge-base, xdiff: zero out xpparam_t structures Michał Kępień
2020-10-15  7:24     ` [PATCH v3 2/2] diff: add -I<regex> that ignores matching changes Michał Kępień
2020-10-16 15:32       ` Phillip Wood
2020-10-16 18:04         ` Junio C Hamano
2020-10-19  9:48           ` Michał Kępień
2020-10-16 18:16       ` Junio C Hamano
2020-10-19  9:55         ` Michał Kępień
2020-10-19 17:29           ` Junio C Hamano
2020-10-16 10:00     ` [PATCH v3 0/2] " Johannes Schindelin
2020-10-20  6:48     ` [PATCH v4 " Michał Kępień
2020-10-20  6:48       ` [PATCH v4 1/2] merge-base, xdiff: zero out xpparam_t structures Michał Kępień
2020-10-20  6:48       ` [PATCH v4 2/2] diff: add -I<regex> that ignores matching changes Michał Kępień
2021-02-05 14:13       ` [PATCH 1/2] diff: add an API for deferred freeing Ævar Arnfjörð Bjarmason
2021-02-10 16:00         ` Johannes Schindelin
2021-02-11  3:00           ` Ævar Arnfjörð Bjarmason [this message]
2021-02-11  9:40             ` Johannes Schindelin
2021-02-11 10:21               ` Jeff King
2021-02-11 10:45                 ` [PATCH v2 0/2] " Ævar Arnfjörð Bjarmason
2021-02-11 10:45                 ` [PATCH v2 1/2] " Ævar Arnfjörð Bjarmason
2021-02-11 10:45                 ` [PATCH v2 2/2] diff: plug memory leak from regcomp() on {log,diff} -I Ævar Arnfjörð Bjarmason
2021-02-05 14:13       ` [PATCH " Ævar Arnfjörð Bjarmason

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

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

  git send-email \
    --in-reply-to=878s7vcnqo.fsf@evledraar.gmail.com \
    --to=avarab@gmail.com \
    --cc=Johannes.Schindelin@gmx.de \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=michal@isc.org \
    --cc=phillip.wood123@gmail.com \
    /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.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.