[#60404] is RB_GC_GUARD needed in rb_io_syswrite? — Eric Wong <normalperson@...>
I haven't gotten it to crash as-is, but it seems like we need to
4 messages
2014/02/01
[#60682] volatile usages — Eric Wong <normalperson@...>
Hi all, I went ahead and removed some use of volatile which were once
5 messages
2014/02/13
[#60794] [RFC] rearrange+pack vtm and time_object structs — Eric Wong <normalperson@...>
Extracted from addendum on top of Feature #9362 (cache-aligned objects).
4 messages
2014/02/16
[#61139] [ruby-trunk - Feature #9577] [Open] [PATCH] benchmark/driver.rb: align columns in text output — normalperson@...
Issue #9577 has been reported by Eric Wong.
3 messages
2014/02/28
[ruby-core:60928] Re: [ruby-trunk - Bug #9356] TCPSocket.new does not seem to handle INTR
From:
Eric Wong <normalperson@...>
Date:
2014-02-21 07:31:54 UTC
List:
ruby-core #60928
shugo@ruby-lang.org wrote:
> Eric Wong wrote:
> > Anyways, I have an alternative (v3) patch here which retries connect()
> > on EINTR and ERESTART:
> > http://bogomips.org/ruby.git/patch?id=8f48b1862
> > (also note my new switch/case style to avoid inline ifdef :)
> >
> > However, I still prefer my v2 if possible:
> > http://bogomips.org/ruby.git/patch?id=f5e2eb00e5
>
> I prefer the latter too, but is `break` missing in the case clause?
I don't usually add it for the last case... Do some compilers need it?
> Linux's man page of connect(2) says it's conforming to POSIX.1-2001 (in spite of the fact that it returns ERESTART), so I hope we don't need the second connect(). What do you think, Kosaki-san?
>
> Or only retry on ERESTART is enough. We don't need the nested switch statements in the former patch, do we?
I'm not sure... Anyways, I think I may realize what happened with
Charlie's EINTR...
> And I'd like to add the following minimal error handling code to wait_connectable():
I think it is OK with a minor tweak below:
> static int
> wait_connectable(int fd)
> {
> int sockerr;
> socklen_t sockerrlen;
>
> /*
> * Stevens book says, successful finish turn on RB_WAITFD_OUT and
> * failure finish turn on both RB_WAITFD_IN and RB_WAITFD_OUT.
> * So it's enough to wait only RB_WAITFD_OUT and check the pending error
> * by getsockopt().
> *
> * Note: rb_wait_for_single_fd already retries on EINTR/ERESTART
> */
> int revents = rb_wait_for_single_fd(fd, RB_WAITFD_OUT, NULL);
>
> if (revents < 0)
> rb_bug_errno("rb_wait_for_single_fd used improperly", errno);
>
> sockerrlen = (socklen_t)sizeof(sockerr);
> if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&sockerr, &sockerrlen) < 0)
> return -1;
> if (sockerr != 0) {
> errno = sockerr;
We should guard against sockerr setting errno to
EINTR, ERESTART, EINPROGRESS, EALREADY, EISCONN here...
Here is what I think happened in Charlie's original case:
connect() -> EINTR, kernel socket remembers this!
retry connect() -> EALREADY
wait_connectable()
rb_wait_for_single_fd() -> success
getsockopt(SO_ERROR), sockerr = EINTR from first connect!
errno = sockerr -> raise :(