[Xcb] [PATCH] Handle EAGAIN errno from poll(2) or select(2)

Jeremy Sequoia jeremyhu at apple.com
Thu Aug 20 00:18:41 PDT 2015


Yeah, I thought about sleeping before retrying in the EAGAIN case to avoid a possible busy loop.  I can do that if you prefer.

As I indicated in the commit message, there is know known fallout from the lack of EAGAIN handling.  There is no behavioral problem.  Indeed the only time someone should ever get back EAGAIN from poll or select on darwin is under resource pressure, and its likely the user would have bigger concerns than this at that point.

I just happened to notice this while tracing code to figure out why someone on stackoverflow was seeing recv() of the DISPLAY socket erring out with EAGAIN and then hanging.

Sent from my iPhone...

On Aug 19, 2015, at 23:59, Mark Kettenis <mark.kettenis at xs4all.nl> wrote:

>> From: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
>> Date: Wed, 19 Aug 2015 16:09:33 -0700
>> 
>> No known fallout from this, but I spotted the possible issue when auditing
>> this code to track down a related issue.  While not noted in SUS, some
>> implementations (like darwin) may return EAGAIN for (possibly) transient
>> kernel issues that would suggest trying again.
> 
> Well, EAGAIN suggests "try again *later*".  Presumably the kernel
> would return EAGAIN immediately and therefore this change may very
> well introduce a spinning loop.  That would not be good, and I'd say
> returning an error would be preferable over having the application
> spin.
> 
> Having the kernel return EAGAIN for a blocking poll or select would be
> a serious bug IMHB.  It should just wait until resources are
> available.  Does Darwin really have such a bug, or are you just trying
> to strike pre-emptively?
> 
>> Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
>> ---
>> src/xcb_conn.c | 2 +-
>> src/xcb_in.c   | 4 ++--
>> 2 files changed, 3 insertions(+), 3 deletions(-)
>> 
>> diff --git a/src/xcb_conn.c b/src/xcb_conn.c
>> index 7d09637..7e49384 100644
>> --- a/src/xcb_conn.c
>> +++ b/src/xcb_conn.c
>> @@ -487,7 +487,7 @@ int _xcb_conn_wait(xcb_connection_t *c, pthread_cond_t *cond, struct iovec **vec
>> #else
>>         ret = select(c->fd + 1, &rfds, &wfds, 0, 0);
>> #endif
>> -    } while (ret == -1 && errno == EINTR);
>> +    } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
>>     if(ret < 0)
>>     {
>>         _xcb_conn_shutdown(c, XCB_CONN_ERROR);
>> diff --git a/src/xcb_in.c b/src/xcb_in.c
>> index bab4bc7..e806388 100644
>> --- a/src/xcb_in.c
>> +++ b/src/xcb_in.c
>> @@ -386,7 +386,7 @@ static int read_block(const int fd, void *buf, const ssize_t len)
>>             pfd.revents = 0;
>>             do {
>>                 ret = poll(&pfd, 1, -1);
>> -            } while (ret == -1 && errno == EINTR);
>> +            } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
>> #else
>>             fd_set fds;
>>             FD_ZERO(&fds);
>> @@ -396,7 +396,7 @@ static int read_block(const int fd, void *buf, const ssize_t len)
>>             errno = 0;
>>             do {
>>                 ret = select(fd + 1, &fds, 0, 0, 0);
>> -            } while (ret == -1 && errno == EINTR);
>> +            } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
>> #endif /* USE_POLL */
>>         }
>>         if(ret <= 0)
>> -- 
>> 2.5.0
>> 
>> _______________________________________________
>> Xcb mailing list
>> Xcb at lists.freedesktop.org
>> https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.freedesktop.org_mailman_listinfo_xcb&d=BQIBAg&c=eEvniauFctOgLOKGJOplqw&r=UaoPsU3Wgwl0YJPmjBVM0jyEVkD-hIP4wNFk_7YgTEE&m=sKrzD564Mp5jpuqjBANoZGDJo7bM8NKbzP2DfayAcf0&s=gwaPnxNJ45yt4eV_0PFKxBLp063hfi28x3Qx3JpFdiU&e= 
>> 
>> 


More information about the Xcb mailing list