* [PATCH] UNIXSocket#recv_io: GC for FDs
@ 2018-06-24 21:49 Eric Wong
0 siblings, 0 replies; only message in thread
From: Eric Wong @ 2018-06-24 21:49 UTC (permalink / raw)
To: spew; +Cc: Eric Wong
---
ext/socket/unixsocket.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/ext/socket/unixsocket.c b/ext/socket/unixsocket.c
index 75f17d6c10..b05f3b9c55 100644
--- a/ext/socket/unixsocket.c
+++ b/ext/socket/unixsocket.c
@@ -339,6 +339,8 @@ unix_recv_io(int argc, VALUE *argv, VALUE sock)
struct iomsg_arg arg;
struct iovec vec[2];
char buf[1];
+ unsigned int gc_reason = 0;
+ enum { GC_REASON_EMSGSIZE = 0x1, GC_REASON_TRUNCATE = 0x2 };
int fd;
#if FD_PASSING_BY_MSG_CONTROL
@@ -354,6 +356,7 @@ unix_recv_io(int argc, VALUE *argv, VALUE sock)
if (argc <= 1)
mode = Qnil;
+retry:
GetOpenFile(sock, fptr);
arg.msg.msg_name = NULL;
@@ -381,12 +384,25 @@ unix_recv_io(int argc, VALUE *argv, VALUE sock)
arg.fd = fptr->fd;
while ((int)BLOCKING_REGION_FD(recvmsg_blocking, &arg) == -1) {
+ int e = errno;
+ if (e == EMSGSIZE && !(gc_reason & GC_REASON_EMSGSIZE)) {
+ /* FreeBSD gets here when we're out of FDs */
+ gc_reason |= GC_REASON_EMSGSIZE;
+ rb_gc_for_fd(EMFILE);
+ goto retry;
+ }
if (!rb_io_wait_readable(arg.fd))
- rsock_sys_fail_path("recvmsg(2)", fptr->pathv);
+ rsock_syserr_fail_path(e, "recvmsg(2)", fptr->pathv);
}
#if FD_PASSING_BY_MSG_CONTROL
if (arg.msg.msg_controllen < (socklen_t)sizeof(struct cmsghdr)) {
+ /* FreeBSD and Linux both get here when we're out of FDs */
+ if (!(gc_reason & GC_REASON_TRUNCATE)) {
+ gc_reason |= GC_REASON_TRUNCATE;
+ rb_gc_for_fd(EMFILE);
+ goto retry;
+ }
rb_raise(rb_eSocket,
"file descriptor was not passed (msg_controllen=%d smaller than sizeof(struct cmsghdr)=%d)",
(int)arg.msg.msg_controllen, (int)sizeof(struct cmsghdr));
--
EW
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2018-06-24 21:50 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-06-24 21:49 [PATCH] UNIXSocket#recv_io: GC for FDs Eric Wong
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 read-only IMAP folder(s) and NNTP newsgroup(s).