Allow listened conversations to be non-blocking
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 22 Jul 2015 12:02:45 +0000 (08:02 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 24 Jul 2015 07:39:30 +0000 (03:39 -0400)
If you listen with O_NONBLOCK, the new conversation you get back is
already set to non-blocking.  In the same way that you open "clone" and
get a ctl fd for the new conversation, so too you open "listen" and get
back a ctl.  The flags to open affect the new conversation.

In the case of listen, opening listen with O_NONBLOCK does not make
listen non-blocking; it makes the *new* conv non-blocking.  To make the
listen non-blocking, you either use a ctl message or open the *clone*
for that conversation with O_NONBLOCK.

kern/src/net/devip.c

index 88f46c3..9abefc7 100644 (file)
@@ -515,9 +515,10 @@ static struct chan *ipopen(struct chan *c, int omode)
                                        cv->incall = nc->next;
                                        mkqid(&c->qid, QID(PROTO(c->qid), nc->x, Qctl), 0, QTFILE);
                                        kstrdup(&cv->owner, ATTACHER(c));
-                                       /* TODO: If we want to support something like accept4(),
-                                        * where the new conversations are nonblocking right away,
-                                        * we can do so here. */
+                                       /* O_NONBLOCK/CNONBLOCK when opening listen means the *new*
+                                        * conv is already non-blocking, like accept4() in Linux */
+                                       if (c->flag & CNONBLOCK)
+                                               Fsconvnonblock(nc, TRUE);
                                }
                                qunlock(&cv->qlock);