mirror of
https://github.com/ruby/ruby.git
synced 2025-08-24 05:25:34 +02:00
merge revision(s) 63304: [Backport #14713]
io.c: workaround for EPROTOTYPE * io.c (internal_write_func, internal_writev_func): retry at unexpected EPROTOTYPE on macOS, to get rid of a kernel bug. [ruby-core:86690] [Bug #14713] * ext/socket/init.c (rsock_{sendto,send,write}_blocking): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_5@63826 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
4a625f839c
commit
fcb4a3d88f
4 changed files with 35 additions and 8 deletions
|
@ -56,6 +56,12 @@ is_socket(int fd)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined __APPLE__
|
||||
# define do_write_retry(code) do {ret = code;} while (ret == -1 && errno == EPROTOTYPE)
|
||||
#else
|
||||
# define do_write_retry(code) ret = code
|
||||
#endif
|
||||
|
||||
VALUE
|
||||
rsock_init_sock(VALUE sock, int fd)
|
||||
{
|
||||
|
@ -83,8 +89,10 @@ rsock_sendto_blocking(void *data)
|
|||
{
|
||||
struct rsock_send_arg *arg = data;
|
||||
VALUE mesg = arg->mesg;
|
||||
return (VALUE)sendto(arg->fd, RSTRING_PTR(mesg), RSTRING_LEN(mesg),
|
||||
arg->flags, arg->to, arg->tolen);
|
||||
ssize_t ret;
|
||||
do_write_retry(sendto(arg->fd, RSTRING_PTR(mesg), RSTRING_LEN(mesg),
|
||||
arg->flags, arg->to, arg->tolen));
|
||||
return (VALUE)ret;
|
||||
}
|
||||
|
||||
VALUE
|
||||
|
@ -92,8 +100,10 @@ rsock_send_blocking(void *data)
|
|||
{
|
||||
struct rsock_send_arg *arg = data;
|
||||
VALUE mesg = arg->mesg;
|
||||
return (VALUE)send(arg->fd, RSTRING_PTR(mesg), RSTRING_LEN(mesg),
|
||||
arg->flags);
|
||||
ssize_t ret;
|
||||
do_write_retry(send(arg->fd, RSTRING_PTR(mesg), RSTRING_LEN(mesg),
|
||||
arg->flags));
|
||||
return (VALUE)ret;
|
||||
}
|
||||
|
||||
struct recvfrom_arg {
|
||||
|
@ -366,10 +376,18 @@ rsock_write_nonblock(VALUE sock, VALUE str, VALUE ex)
|
|||
rb_io_flush(sock);
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
again:
|
||||
#endif
|
||||
n = (long)send(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str), MSG_DONTWAIT);
|
||||
if (n < 0) {
|
||||
int e = errno;
|
||||
|
||||
#ifdef __APPLE__
|
||||
if (e == EPROTOTYPE) {
|
||||
goto again;
|
||||
}
|
||||
#endif
|
||||
if (e == EWOULDBLOCK || e == EAGAIN) {
|
||||
if (ex == Qfalse) return sym_wait_writable;
|
||||
rb_readwrite_syserr_fail(RB_IO_WAIT_WRITABLE, e,
|
||||
|
|
13
io.c
13
io.c
|
@ -937,11 +937,18 @@ internal_read_func(void *ptr)
|
|||
return read(iis->fd, iis->buf, iis->capa);
|
||||
}
|
||||
|
||||
#if defined __APPLE__
|
||||
# define do_write_retry(code) do {ret = code;} while (ret == -1 && errno == EPROTOTYPE)
|
||||
#else
|
||||
# define do_write_retry(code) ret = code
|
||||
#endif
|
||||
static VALUE
|
||||
internal_write_func(void *ptr)
|
||||
{
|
||||
struct io_internal_write_struct *iis = ptr;
|
||||
return write(iis->fd, iis->buf, iis->capa);
|
||||
ssize_t ret;
|
||||
do_write_retry(write(iis->fd, iis->buf, iis->capa));
|
||||
return (VALUE)ret;
|
||||
}
|
||||
|
||||
static void*
|
||||
|
@ -956,7 +963,9 @@ static VALUE
|
|||
internal_writev_func(void *ptr)
|
||||
{
|
||||
struct io_internal_writev_struct *iis = ptr;
|
||||
return writev(iis->fd, iis->iov, iis->iovcnt);
|
||||
ssize_t ret;
|
||||
do_write_retry(writev(iis->fd, iis->iov, iis->iovcnt));
|
||||
return (VALUE)ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -425,7 +425,7 @@ class FTPTest < Test::Unit::TestCase
|
|||
end
|
||||
conn.print(l, "\r\n")
|
||||
end
|
||||
rescue Errno::EPIPE, Errno::EPROTOTYPE
|
||||
rescue Errno::EPIPE
|
||||
ensure
|
||||
assert_nil($!)
|
||||
conn.close
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#define RUBY_VERSION "2.5.2"
|
||||
#define RUBY_RELEASE_DATE "2018-07-02"
|
||||
#define RUBY_PATCHLEVEL 64
|
||||
#define RUBY_PATCHLEVEL 65
|
||||
|
||||
#define RUBY_RELEASE_YEAR 2018
|
||||
#define RUBY_RELEASE_MONTH 7
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue