From: Stefan Beller <sbeller@google.com>
To: "Torsten Bögershausen" <tboegi@web.de>
Cc: "git@vger.kernel.org" <git@vger.kernel.org>,
Junio C Hamano <gitster@pobox.com>, Jeff King <peff@peff.net>,
Jonathan Nieder <jrnieder@gmail.com>,
Johannes Schindelin <johannes.schindelin@gmail.com>,
Jens Lehmann <Jens.Lehmann@web.de>,
Eric Sunshine <ericsunshine@gmail.com>,
Johannes Sixt <j6t@kdbg.org>
Subject: Re: [PATCHv2 2/7] xread: poll on non blocking fds
Date: Thu, 17 Dec 2015 12:51:08 -0800 [thread overview]
Message-ID: <CAGZ79kYHjH7QgChn6_GU9iLrtyouFQFuMAZKADZofgHjBS73-A@mail.gmail.com> (raw)
In-Reply-To: <56731E19.7050504@web.de>
On Thu, Dec 17, 2015 at 12:42 PM, Torsten Bögershausen <tboegi@web.de> wrote:
> On 17.12.15 21:22, Stefan Beller wrote:
>> On Thu, Dec 17, 2015 at 12:12 PM, Torsten Bögershausen <tboegi@web.de> wrote:
>>> On 16.12.15 01:04, Stefan Beller wrote:
>>>> The man page of read(2) says:
>>>>
>>>> EAGAIN The file descriptor fd refers to a file other than a socket
>>>> and has been marked nonblocking (O_NONBLOCK), and the read
>>>> would block.
>>>>
>>>> EAGAIN or EWOULDBLOCK
>>>> The file descriptor fd refers to a socket and has been marked
>>>> nonblocking (O_NONBLOCK), and the read would block. POSIX.1-2001
>>>> allows either error to be returned for this case, and does not
>>>> require these constants to have the same value, so a portable
>>>> application should check for both possibilities.
>>>>
>>>> If we get an EAGAIN or EWOULDBLOCK the fd must have set O_NONBLOCK.
>>>> As the intent of xread is to read as much as possible either until the
>>>> fd is EOF or an actual error occurs, we can ease the feeder of the fd
>>>> by not spinning the whole time, but rather wait for it politely by not
>>>> busy waiting.
>>>>
>>>> We should not care if the call to poll failed, as we're in an infinite
>>>> loop and can only get out with the correct read().
>>> I'm not sure if this is valid under all circumstances:
>>> This is what "man poll" says under Linux:
>>> []
>>> ENOMEM There was no space to allocate file descriptor tables.
>>> []
>>> And this is from Mac OS, ("BSD System Calls Manual")
>>> ERRORS
>>> Poll() will fail if:
>>>
>>> [EAGAIN] Allocation of internal data structures fails. A sub-
>>> sequent request may succeed.
>>> And this is opengroup:
>>> http://pubs.opengroup.org/onlinepubs/9699919799//functions/poll.html:
>>> [EAGAIN]
>>> The allocation of internal data structures failed but a subsequent request may succeed.
>>>
>>> read() may return EAGAIN, but poll() may fail to allocate memory, and fail.
>>> Is it always guaranteed that the loop is terminated?
>>
>> In case poll fails (assume a no op for it), the logic should not have
>> changed by this patch?
>>
>> Looking closely:
>>
>>>> while (1) {
>>>> nr = read(fd, buf, len);
>>>> - if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
>>>> - continue;
>>>> + if (nr < 0) {
>>>> + if (errno == EINTR)
>>>> + continue;
>>>> + if (errno == EAGAIN || errno == EWOULDBLOCK) {
>>>> + struct pollfd pfd;
>>>> + pfd.events = POLLIN;
>>>> + pfd.fd = fd;
>>>> + /*
>>>> + * it is OK if this poll() failed; we
>>>> + * want to leave this infinite loop
>>>> + * only when read() returns with
>>>> + * success, or an expected failure,
>>>> + * which would be checked by the next
>>>> + * call to read(2).
>>>> + */
>>>> + poll(&pfd, 1, -1);
>>
>> Or do you mean to insert another continue in here?
> I was thinking that we run into similar loop as before:
> read() returns -1; errno = EAGAIN /* No data to read */
which is expected for non blocking fds,
> poll() returns -1; errno = EAGAIN /* poll failed. If the fd was OK, the failure may be temporaly,
> as much as poll() can see.
> But most probably we run out ouf memory */
Before this patch we would not have asked poll, but had just a continue here,
so I think we need to have it here again no matter of the return code
of the poll.
If poll determines it is low on memory, this should not make this function fail,
we can still do as good as we did before by just asking read
repeatedly again, though?
So I'd be convinced now we'd want to have:
poll(&pfd, 1, -1); /* this is only buying time
for the fd to deliver data, in case it fails
we don't care but just fall back to old
behavior before this patch with busy spinning*/
continue;
>
> So the code would look like this:
>
> if (!poll(&pfd, 1, -1))
> return -1;
>
>
>>
>
>>>> + }
>>>> + }
>>>> return nr;
>>>> }
>>>> }
>>>>
>>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe git" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
next prev parent reply other threads:[~2015-12-17 20:51 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-12-16 0:04 [PATCHv2 0/7] Rerolling sb/submodule-parallel-fetch for the time after 2.7 Stefan Beller
2015-12-16 0:04 ` [PATCHv2 1/7] submodule.c: write "Fetching submodule <foo>" to stderr Stefan Beller
2015-12-16 0:04 ` [PATCHv2 2/7] xread: poll on non blocking fds Stefan Beller
2015-12-17 20:12 ` Torsten Bögershausen
2015-12-17 20:22 ` Stefan Beller
2015-12-17 20:42 ` Torsten Bögershausen
2015-12-17 20:51 ` Stefan Beller [this message]
2015-12-18 3:14 ` Jeff King
2015-12-18 3:13 ` Jeff King
2015-12-18 8:50 ` Torsten Bögershausen
2015-12-18 18:12 ` Jeff King
2015-12-18 3:07 ` Jeff King
2015-12-16 0:04 ` [PATCHv2 3/7] strbuf: add strbuf_read_once to read without blocking Stefan Beller
2015-12-16 0:04 ` [PATCHv2 4/7] sigchain: add command to pop all common signals Stefan Beller
2015-12-16 0:04 ` [PATCHv2 5/7] run-command: add an asynchronous parallel child processor Stefan Beller
2015-12-16 0:04 ` [PATCHv2 6/7] fetch_populated_submodules: use new parallel job processing Stefan Beller
2015-12-16 0:04 ` [PATCHv2 7/7] submodules: allow parallel fetching, add tests and documentation Stefan Beller
2015-12-16 0:19 ` [PATCHv2 0/7] Rerolling sb/submodule-parallel-fetch for the time after 2.7 Stefan Beller
2015-12-16 20:20 ` Junio C Hamano
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=CAGZ79kYHjH7QgChn6_GU9iLrtyouFQFuMAZKADZofgHjBS73-A@mail.gmail.com \
--to=sbeller@google.com \
--cc=Jens.Lehmann@web.de \
--cc=ericsunshine@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=j6t@kdbg.org \
--cc=johannes.schindelin@gmail.com \
--cc=jrnieder@gmail.com \
--cc=peff@peff.net \
--cc=tboegi@web.de \
/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 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 NNTP newsgroup(s).