All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: Jeff Hostetler <git@jeffhostetler.com>
Cc: Taylor Blau <me@ttaylorr.com>,
	Jeff Hostetler via GitGitGadget <gitgitgadget@gmail.com>,
	git@vger.kernel.org, Jeff Hostetler <jeffhost@microsoft.com>
Subject: Re: [PATCH 7/7] t/helper/simple-ipc: convert test-simple-ipc to use start_bg_command
Date: Sat, 18 Sep 2021 10:59:10 +0200	[thread overview]
Message-ID: <87ilyycko3.fsf@evledraar.gmail.com> (raw)
In-Reply-To: <aaad241c-4014-729c-32c9-df7039439a77@jeffhostetler.com>


On Fri, Sep 17 2021, Jeff Hostetler wrote:

> On 9/16/21 1:06 AM, Taylor Blau wrote:
>> On Wed, Sep 15, 2021 at 08:36:17PM +0000, Jeff Hostetler via GitGitGadget wrote:
>>> From: Jeff Hostetler <jeffhost@microsoft.com>
>>>
>>> Convert test helper to use `start_bg_command()` when spawning a server
>>> daemon in the background rather than blocks of platform-specific code.
>>>
>>> Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
>>> ---
>>>   t/helper/test-simple-ipc.c | 193 ++++++++-----------------------------
>>>   1 file changed, 40 insertions(+), 153 deletions(-)
>>>
>>> diff --git a/t/helper/test-simple-ipc.c b/t/helper/test-simple-ipc.c
>>> index 91345180750..59a950f3b00 100644
>>> --- a/t/helper/test-simple-ipc.c
>>> +++ b/t/helper/test-simple-ipc.c
>>> @@ -9,6 +9,7 @@
>>>   #include "parse-options.h"
>>>   #include "thread-utils.h"
>>>   #include "strvec.h"
>>> +#include "run-command.h"
>>>
>>>   #ifndef SUPPORTS_SIMPLE_IPC
>>>   int cmd__simple_ipc(int argc, const char **argv)
>>> @@ -274,178 +275,64 @@ static int daemon__run_server(void)
>>>   	return ret;
>>>   }
>>>
>>> -#ifndef GIT_WINDOWS_NATIVE
>>> -/*
>>> - * This is adapted from `daemonize()`.  Use `fork()` to directly create and
>>> - * run the daemon in a child process.
>>> - */
>>> -static int spawn_server(pid_t *pid)
>>> -{
>>> -	struct ipc_server_opts opts = {
>>> -		.nr_threads = cl_args.nr_threads,
>>> -	};
>>> +static start_bg_wait_cb bg_wait_cb;
>> This whole patch is delightful to read, as the new implementation is
>> so
>> much cleaner as a result of the earlier work in this series.
>> Am I correct in assuming that this is to encourage a compiler error
>> if
>> bg_wait_cb does not satisfy the type of start_bg_wait_cb? If so, then I
>> think we are already getting that by trying to pass bg_wait_cb to
>> start_bg_command().
>
> I use that trick to get the compiler to give me a compiler error at the
> point of the function declaration.
>
> For example, If I add an arg to the function that doesn't match what's
> in the prototype definition, I get:
>
> t/helper/test-simple-ipc.c:280:12: error: conflicting types for 'bg_wait_cb'
> static int bg_wait_cb(const struct child_process *cp, void *cb_data,
> int foo)
>            ^
> t/helper/test-simple-ipc.c:278:25: note: previous declaration is here
> static start_bg_wait_cb bg_wait_cb;
>                         ^
> 1 error generated.
>
> Yes, we may get an error when the function pointer is referenced in
> start_bg_command() or if we're using it to initialize a vtable or
> something, but those errors are further away from the actual error
> (and sometimes they can be a little cryptic).
>
> Also, it helps document that this function's signature is predefined
> for a reason.
>
> It's a quirky trick I know, but it has served me well over the years.

I haven't seen this idiom before. I think it's best to avoid patterns
designed to massage messages out of any specific compilers/versions.

It seems inevitable that it'll either be counter-productive or
redundant. Here with clang v11 doing this makes the warning
worse. I.e. without the forward declaration:

    t/helper/test-simple-ipc.c:315:31: error: incompatible function
    pointer types passing 'int (void *, const struct child_process *,
    int)' to parameter of type ' start_bg_wait_cb *' (aka 'int (*)(void
    *, const struct child_process *)')
    [-Werror,-Wincompatible-function-pointer-types]
            sbgr = start_bg_command(&cp, bg_wait_cb, NULL, cl_args.max_wait_sec);
                                         ^~~~~~~~~~
    ./run-command.h:564:29: note: passing argument to parameter 'wait_cb' here
                                      start_bg_wait_cb *wait_cb,
                                                        ^
    1 error generated.

I.e. we get the specific warning category for this type of error
(-Werror,-Wincompatible-function-pointer-types), and we're pointed at
the caller in question (which to be fair, it seems you don't prefer),
but also a reference to the run-command.h definition.

Most importantly, we get quoted what the type is/should be, which is
missing with the forward declaration. It's the equivalent of saying "you
did bad!" instead of "you did bad X, do Y instead!".

>> E.g., applying this (intentionally broken) diff on top:
>> --- 8< ---
>> diff --git a/t/helper/test-simple-ipc.c b/t/helper/test-simple-ipc.c
>> index 59a950f3b0..3aed787206 100644
>> --- a/t/helper/test-simple-ipc.c
>> +++ b/t/helper/test-simple-ipc.c
>> @@ -275,9 +275,7 @@ static int daemon__run_server(void)
>>   	return ret;
>>   }
>> -static start_bg_wait_cb bg_wait_cb;
>> -
>> -static int bg_wait_cb(void *cb_data, const struct child_process *cp)
>> +static int bg_wait_cb(const void *cb_data, const struct child_process *cp)
>>   {
>>   	int s = ipc_get_active_state(cl_args.path);
>> --- >8 ---
>> and then compiling still warns of a mismatched type when calling
>> start_bg_command().
>> 
>>> -	*pid = fork();
>>> -
>>> -	switch (*pid) {
>>> -	case 0:
>>> -		if (setsid() == -1)
>>> -			error_errno(_("setsid failed"));
>>> -		close(0);
>>> -		close(1);
>>> -		close(2);
>>> -		sanitize_stdfds();
>>> +static int bg_wait_cb(void *cb_data, const struct child_process *cp)
>>> +{
>>> +	int s = ipc_get_active_state(cl_args.path);
>>>
>>> -		return ipc_server_run(cl_args.path, &opts, test_app_cb,
>>> -				      (void*)&my_app_data);
>>> +	switch (s) {
>>> +	case IPC_STATE__LISTENING:
>>> +		/* child is "ready" */
>>> +		return 0;
>>>
>>> -	case -1:
>>> -		return error_errno(_("could not spawn daemon in the background"));
>>> +	case IPC_STATE__NOT_LISTENING:
>>> +	case IPC_STATE__PATH_NOT_FOUND:
>>> +		/* give child more time */
>>> +		return 1;
>>>
>>>   	default:
>> I'm always a little hesitant to have default cases when switch over
>> enum
>> types, since it suppresses the warning when there's a new value of that
>> type. But we already have a similar default in client__probe_server().
>
> Do all compilers now handle switching over an enum and detect unhandled
> cases?  Once upon a time that wasn't the case IIRC.

I don't think so, but the ones we widely use do, i.e. clang and gcc at
least.

For this sort of thing it really doesn't matter if *all* compilers
support it, since we'll only need to catch such "missing enum arm"
issues with one of them.

E.g. in my 338abb0f045 (builtins + test helpers: use return instead of
exit() in cmd_*, 2021-06-08) I fixed something that I've only gotten
Oracle SunCC to emit (gcc and clang don't detect it), but as long as
that one compiler does & someone checks it regularly...

By having a "default" case you're hiding that detection from the
compilers capable of detecting a logic error in this code, whereas if
the compiler can't do that it'll just ignore it.

  reply	other threads:[~2021-09-18  9:12 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-15 20:36 [PATCH 0/7] Builtin FSMonitor Part 1 Jeff Hostetler via GitGitGadget
2021-09-15 20:36 ` [PATCH 1/7] trace2: fix memory leak of thread name Jeff Hostetler via GitGitGadget
2021-09-15 21:01   ` Junio C Hamano
2021-09-16  4:19     ` Taylor Blau
2021-09-16  5:35   ` Ævar Arnfjörð Bjarmason
2021-09-16  5:43     ` Taylor Blau
2021-09-16  8:01       ` Ævar Arnfjörð Bjarmason
2021-09-16 15:35         ` Jeff Hostetler
2021-09-16 15:47           ` Ævar Arnfjörð Bjarmason
2021-09-16 19:13         ` Junio C Hamano
2021-09-15 20:36 ` [PATCH 2/7] simple-ipc: preparations for supporting binary messages Jeff Hostetler via GitGitGadget
2021-09-15 20:43   ` Eric Sunshine
2021-09-17 16:52     ` Jeff Hostetler
2021-09-15 20:36 ` [PATCH 3/7] simple-ipc: move definition of ipc_active_state outside of ifdef Jeff Hostetler via GitGitGadget
2021-09-15 21:06   ` Junio C Hamano
2021-09-17 16:58     ` Jeff Hostetler
2021-09-18  7:03       ` Carlo Arenas
2021-09-20 15:51       ` Junio C Hamano
2021-09-15 20:36 ` [PATCH 4/7] simple-ipc/ipc-win32: add trace2 debugging Jeff Hostetler via GitGitGadget
2021-09-16  5:40   ` Ævar Arnfjörð Bjarmason
2021-09-17 17:27     ` Jeff Hostetler
2021-09-15 20:36 ` [PATCH 5/7] simple-ipc/ipc-win32: add Windows ACL to named pipe Jeff Hostetler via GitGitGadget
2021-09-16  5:47   ` Ævar Arnfjörð Bjarmason
2021-09-17 18:10     ` Jeff Hostetler
2021-09-17 19:14       ` Ævar Arnfjörð Bjarmason
2021-09-15 20:36 ` [PATCH 6/7] run-command: create start_bg_command Jeff Hostetler via GitGitGadget
2021-09-16  4:53   ` Taylor Blau
2021-09-16  4:58     ` Taylor Blau
2021-09-16  5:56   ` Ævar Arnfjörð Bjarmason
2021-09-15 20:36 ` [PATCH 7/7] t/helper/simple-ipc: convert test-simple-ipc to use start_bg_command Jeff Hostetler via GitGitGadget
2021-09-16  5:06   ` Taylor Blau
2021-09-17 19:41     ` Jeff Hostetler
2021-09-18  8:59       ` Ævar Arnfjörð Bjarmason [this message]
2021-09-16  5:55   ` Ævar Arnfjörð Bjarmason
2021-09-20 15:36 ` [PATCH v2 0/7] Builtin FSMonitor Part 1 Jeff Hostetler via GitGitGadget
2021-09-20 15:36   ` [PATCH v2 1/7] trace2: add trace2_child_ready() to report on background children Jeff Hostetler via GitGitGadget
2021-09-20 15:36   ` [PATCH v2 2/7] simple-ipc: preparations for supporting binary messages Jeff Hostetler via GitGitGadget
2021-09-20 15:36   ` [PATCH v2 3/7] simple-ipc: move definition of ipc_active_state outside of ifdef Jeff Hostetler via GitGitGadget
2021-09-20 15:36   ` [PATCH v2 4/7] simple-ipc/ipc-win32: add trace2 debugging Jeff Hostetler via GitGitGadget
2021-09-20 15:36   ` [PATCH v2 5/7] simple-ipc/ipc-win32: add Windows ACL to named pipe Jeff Hostetler via GitGitGadget
2021-09-20 15:36   ` [PATCH v2 6/7] run-command: create start_bg_command Jeff Hostetler via GitGitGadget
2021-09-20 15:36   ` [PATCH v2 7/7] t/helper/simple-ipc: convert test-simple-ipc to use start_bg_command Jeff Hostetler via GitGitGadget
2021-09-23 15:03     ` Ævar Arnfjörð Bjarmason
2021-09-23 17:58       ` Jeff Hostetler
2021-09-23 18:37       ` Junio C Hamano
2021-11-04 19:46     ` Adam Dinwoodie
2021-11-04 20:14       ` Ramsay Jones
2021-11-08 14:58       ` Jeff Hostetler
2021-11-08 23:59       ` Johannes Schindelin
2021-11-09 18:53         ` Ramsay Jones
2021-11-09 23:01           ` Johannes Schindelin
2021-11-09 23:34             ` Junio C Hamano
2021-11-10 12:27               ` Johannes Schindelin
2021-11-12  8:56                 ` Adam Dinwoodie
2021-11-12 16:01                   ` Junio C Hamano
2021-11-12 21:33                     ` Adam Dinwoodie
2021-11-16 10:56                       ` Johannes Schindelin
2021-11-16 11:02                   ` Johannes Schindelin
2021-11-13 19:11                 ` Ramsay Jones
2021-11-14 19:34                   ` Ramsay Jones
2021-11-14 20:10                   ` Adam Dinwoodie
2021-09-23 14:33   ` [PATCH v2 0/7] Builtin FSMonitor Part 1 Ævar Arnfjörð Bjarmason
2021-09-23 17:12     ` Jeff Hostetler
2021-09-23 20:47       ` Ævar Arnfjörð Bjarmason
2021-09-27 13:37         ` Jeff Hostetler
2021-09-23 17:51     ` Taylor Blau

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=87ilyycko3.fsf@evledraar.gmail.com \
    --to=avarab@gmail.com \
    --cc=git@jeffhostetler.com \
    --cc=git@vger.kernel.org \
    --cc=gitgitgadget@gmail.com \
    --cc=jeffhost@microsoft.com \
    --cc=me@ttaylorr.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.