dumping ground for random patches and texts
 help / color / mirror / Atom feed
* [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).