Subject: Re: [PATCH v3] daemon: correctly handle soft accept() errors in service_loop

From: Junio C Hamano <[email-masked]>
Date: Mon, 30 Jun 2025 08:33:31 -0700

Phillip Wood <[email-masked]> writes:

> Hi Carlo
> This looks good
> Thanks
> Phillip

Thanks, both of you.  Shall we mark the topic for 'next', then?

> On 28/06/2025 00:14, Carlo Marcelo Arenas Belón wrote:
>> Since df076bdbcc ([PATCH] GIT: Listen on IPv6 as well, if available.,
>> 2005-07-23), the original error checking was included in an inner loop
>> unchanged, where its effect was different.
>> Instead of retrying, after a EINTR during accept() in the listening
>> socket, it will advance to the next one and try with that instead,
>> leaving the client waiting for another round.
>> Make sure to retry with the same listener socket that failed
>> originally.
>> To avoid an unlikely busy loop, fallback to the old behaviour after
>> a
>> couple of attempts.
>> Signed-off-by: Carlo Marcelo Arenas Belón <[email-masked]>
>> ---
>>   daemon.c | 12 ++++++++++--
>>   1 file changed, 10 insertions(+), 2 deletions(-)
>> diff --git a/daemon.c b/daemon.c
>> index d1be61fd57..9ac9efa17c 100644
>> --- a/daemon.c
>> +++ b/daemon.c
>> @@ -1153,11 +1153,19 @@ static int service_loop(struct socketlist *socklist)
>>   #endif
>>   				} ss;
>>   				socklen_t sslen = sizeof(ss);
>> -				int incoming = accept(pfd[i].fd, &ss.sa, &sslen);
>> +				int incoming;
>> +				int retry = 3;
>> +
>> +			redo:
>> +				incoming = accept(pfd[i].fd, &ss.sa, &sslen);
>>   				if (incoming < 0) {
>>   					switch (errno) {
>> -					case EAGAIN:
>>   					case EINTR:
>> +						if (--retry)
>> +							goto redo;
>> +
>> +						/* fallthrough */
>> +					case EAGAIN:
>>   					case ECONNABORTED:
>>   						continue;
>>   					default: