git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 09/26] upload-pack: move rev-list code out of check_non_tip()

From
Eric Sunshine <sunshine@sunshineco.com>
Date
May 25, 2016, 07:36 UTC
Message-ID
<CAPig+cRM_6Yj0=ZOwf8xq9fipCVOFVVLeh5yOpqTxrq4r314iw@mail.gmail.com>
In-Reply-To
<1460552110-5554-10-git-send-email-pclouds@gmail.com>
On Wed, Apr 13, 2016 at 8:54 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:
Show 34 quoted lines
> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
> ---
> diff --git a/upload-pack.c b/upload-pack.c
> @@ -451,7 +451,7 @@ static int is_our_ref(struct object *o)
> -static void check_non_tip(void)
> +static int check_unreachable(struct object_array *src)
> @@ -461,14 +461,6 @@ static void check_non_tip(void)
> -       /*
> -        * In the normal in-process case without
> -        * uploadpack.allowReachableSHA1InWant,
> -        * non-tip requests can never happen.
> -        */
> -       if (!stateless_rpc && !(allow_unadvertised_object_request & ALLOW_REACHABLE_SHA1))
> -               goto error;
> -
> @@ -476,7 +468,7 @@ static void check_non_tip(void)
>         if (start_command(&cmd))
> -               goto error;
> +               return 0;
> @@ -495,16 +487,16 @@ static void check_non_tip(void)
>                 if (write_in_full(cmd.in, namebuf, 42) < 0)
> -                       goto error;
> +                       return 0;
> [...]
> +       for (i = 0; i < src->nr; i++) {
> +               o = src->objects[i].item;
>                 if (is_our_ref(o))
>                         continue;
>                 memcpy(namebuf, oid_to_hex(&o->oid), GIT_SHA1_HEXSZ);
>                 if (write_in_full(cmd.in, namebuf, 41) < 0)
> -                       goto error;
> +                       return 0;
>         }
>         close(cmd.in);

It's a little bit ugly how this close() becomes disconnected after the refactoring. In the original code, due to the consistent application of 'goto error', it's reasonably obvious that skipping the close() is not harmful since the error case die()'s unconditionally (according to the comment). However, after the refactoring, the function simply returns without invoking close(), so there's a disconnect, and it's not obvious without looking at the caller that the program will die().

Also, if this function later gets a new caller, is that caller going to need intimate knowledge about this potential descriptor leak?

Show 7 quoted lines
> @@ -516,7 +508,7 @@ static void check_non_tip(void)
>          */
>         i = read_in_full(cmd.out, namebuf, 1);
>         if (i)
> -               goto error;
> +               return 0;
>         close(cmd.out);
Same observation.

It might be clearer if you retained the 'error' label and used it to ensure that the descriptors get closed:

    cmd.in = -1;
    cmd.out = -1;
    ...
    if (...)
        goto error;
    ...
    /* All the non-tip ... */
    return 1;
error:
    if (cmd.in >= 0)
        close(cmd.in);
    if (cmd.out >= 0)
        close(cmd.out);
    return 0;
Show 7 quoted lines
>         /*
> @@ -525,15 +517,29 @@ static void check_non_tip(void)
>          * even when it showed no commit.
>          */
>         if (finish_command(&cmd))
> -               goto error;
> +               return 0;

Here too. Does 'cmd' need to be cleaned up if the function bails before finish_command()?

Show 18 quoted lines
>         /* All the non-tip ones are ancestors of what we advertised */
> -       return;
> +       return 1;
> +}
> +
> +static void check_non_tip(void)
> +{
> +       int i;
> +
> +       /*
> +        * In the normal in-process case without
> +        * uploadpack.allowReachableSHA1InWant,
> +        * non-tip requests can never happen.
> +        */
> +       if (!stateless_rpc && !(allow_unadvertised_object_request & ALLOW_REACHABLE_SHA1))
> +               ;               /* error */
> +       else if (check_unreachable(&want_obj))
> +               return;

With the loss of the 'error' label (below), this logic becomes a bit more difficult to follow. I wonder if it would help to invert the sense of the conditional...

    if (stateless_rpc || ...)
        if (check_unreachable(...))
            return;
Or, perhaps, retain the 'error' label:
    if (!stateless_rpc && ...)
        goto error:
    if (check_unreachable(...))
        return;
error:
    /* Pick one ... */
I think I might find the latter a bit clearer, but it's highly subjective.
Show 8 quoted lines
> -error:
>         /* Pick one of them (we know there at least is one) */
>         for (i = 0; i < want_obj.nr; i++) {
> -               o = want_obj.objects[i].item;
> +               struct object *o = want_obj.objects[i].item;
>                 if (!is_our_ref(o))
>                         die("git upload-pack: not our ref %s",
>                             oid_to_hex(&o->oid));
Previous: Nguyễn Thái Ngọc DuyNext: Nguyễn Thái Ngọc Duy
Message 14 of 40 in “nd/shallow-deepen updates”
  1. 00/26 nd/shallow-deepen updatesNguyễn Thái Ngọc Duy, Apr 13, 2016
  2. 01/26 remote-curl.c: convert fetch_git() to use argv_arrayNguyễn Thái Ngọc Duy, Apr 13, 2016
  3. Eric SunshineMay 25, 2016
  4. 02/26 transport-helper.c: refactor set_helper_option()Nguyễn Thái Ngọc Duy, Apr 13, 2016
  5. Eric SunshineMay 25, 2016
  6. 03/26 upload-pack: move shallow deepen code out of receive_needs()Nguyễn Thái Ngọc Duy, Apr 13, 2016
  7. 04/26 upload-pack: move "shallow" sending code out of deepen()Nguyễn Thái Ngọc Duy, Apr 13, 2016
  8. 05/26 upload-pack: remove unused variable "backup"Nguyễn Thái Ngọc Duy, Apr 13, 2016
  9. 06/26 upload-pack: move "unshallow" sending code out of deepen()Nguyễn Thái Ngọc Duy, Apr 13, 2016
  10. 07/26 upload-pack: use skip_prefix() instead of starts_with()Nguyễn Thái Ngọc Duy, Apr 13, 2016
  11. Eric SunshineMay 25, 2016
  12. 08/26 upload-pack: tighten number parsing at "deepen" linesNguyễn Thái Ngọc Duy, Apr 13, 2016
  13. 09/26 upload-pack: move rev-list code out of check_non_tip()Nguyễn Thái Ngọc Duy, Apr 13, 2016
  14. Eric SunshineMay 25, 2016
  15. 10/26 fetch-pack: use skip_prefix() instead of starts_with()Nguyễn Thái Ngọc Duy, Apr 13, 2016
  16. 11/26 fetch-pack: use a common function for verbose printingNguyễn Thái Ngọc Duy, Apr 13, 2016
  17. 12/26 fetch-pack.c: mark strings for translatingNguyễn Thái Ngọc Duy, Apr 13, 2016
  18. 13/26 fetch-pack: use a separate flag for fetch in deepening modeNguyễn Thái Ngọc Duy, Apr 13, 2016
  19. 14/26 shallow.c: implement a generic shallow boundary finder based on rev-listNguyễn Thái Ngọc Duy, Apr 13, 2016
  20. Eric SunshineMay 27, 2016
  21. 15/26 upload-pack: add deepen-since to cut shallow repos based on timeNguyễn Thái Ngọc Duy, Apr 13, 2016
  22. 16/26 fetch: define shallow boundary with --shallow-sinceNguyễn Thái Ngọc Duy, Apr 13, 2016
  23. 17/26 clone: define shallow clone boundary based on time with --shallow-sinceNguyễn Thái Ngọc Duy, Apr 13, 2016
  24. 18/26 t5500, t5539: tests for shallow depth since a specific dateNguyễn Thái Ngọc Duy, Apr 13, 2016
  25. Eric SunshineJun 5, 2016
  26. 19/26 refs: add expand_ref()Nguyễn Thái Ngọc Duy, Apr 13, 2016
  27. 20/26 upload-pack: support define shallow boundary by excluding revisionsNguyễn Thái Ngọc Duy, Apr 13, 2016
  28. 21/26 fetch: define shallow boundary with --shallow-excludeNguyễn Thái Ngọc Duy, Apr 13, 2016
  29. Eric SunshineJun 5, 2016
  30. 22/26 clone: define shallow clone boundary with --shallow-excludeNguyễn Thái Ngọc Duy, Apr 13, 2016
  31. Eric SunshineJun 5, 2016
  32. 23/26 t5500, t5539: tests for shallow depth excluding a refNguyễn Thái Ngọc Duy, Apr 13, 2016
  33. Eric SunshineJun 5, 2016
  34. 24/26 upload-pack: split check_unreachable() in two, prep for get_reachable_list()Nguyễn Thái Ngọc Duy, Apr 13, 2016
  35. Eric SunshineJun 5, 2016
  36. Duy NguyenJun 10, 2016
  37. 25/26 upload-pack: add get_reachable_list()Nguyễn Thái Ngọc Duy, Apr 13, 2016
  38. Eric SunshineJun 5, 2016
  39. 26/26 fetch, upload-pack: --deepen=N extends shallow boundary by N commitsNguyễn Thái Ngọc Duy, Apr 13, 2016
  40. Junio C HamanoApr 14, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.