Remove epoll's listen_fd acrobatics [2/3]
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 6 Jan 2016 15:40:44 +0000 (10:40 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 14 Jan 2016 21:04:46 +0000 (16:04 -0500)
The Rock code maintains an always-open listen_fd, so epoll no longer
needs to do get and close the FD.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
user/iplib/epoll.c

index 6dbbf49..9e22c2c 100644 (file)
@@ -68,7 +68,6 @@ struct ep_fd_data {
        struct epoll_event                      ep_event;
        int                                                     fd;
        int                                                     filter;
-       int                                                     sock_listen_fd;
 };
 
 /* Converts epoll events to FD taps. */
@@ -189,14 +188,6 @@ static void epoll_close(struct user_fd *ufd)
                ep_fd_i = (struct ep_fd_data*)ceq_ev_i->user_data;
                if (!ep_fd_i)
                        continue;
-               if (ep_fd_i->sock_listen_fd >= 0) {
-                       /* This tap is using a listen_fd, opened by __epoll_ctl_add, so the
-                        * user doesn't know about this FD.  We need to remove the tap and
-                        * close the FD; the kernel will remove the tap when we close it. */
-                       close(ep_fd_i->sock_listen_fd);
-                       free(ep_fd_i);
-                       continue;
-               }
                tap_req_i = &tap_reqs[nr_tap_req++];
                tap_req_i->fd = i;
                tap_req_i->cmd = FDTAP_CMD_REM;
@@ -302,26 +293,14 @@ static int __epoll_ctl_add(struct epoll_ctlr *ep, int fd,
        }
        /* The sockets-to-plan9 networking shims are a bit inconvenient.  The user
         * asked us to epoll on an FD, but that FD is actually a Qdata FD.  We need
-        * to actually epoll on the listen_fd.  We'll store this in the ep_fd, so
-        * that later on we can close it.
+        * to actually epoll on the listen_fd.
         *
         * As far as tracking the FD goes for epoll_wait() reporting, if the app
         * wants to track the FD they think we are using, then they already passed
-        * that in event->data.
-        *
-        * But before we get too far, we need to make sure we aren't already tapping
-        * this FD's listener (hence the lookup).
-        *
-        * This all assumes that this socket is only added to one epoll set at a
-        * time.  The _sock calls are racy, and once one epoller set up a listen_fd
-        * in the Rock, we'll think that it was us. */
+        * that in event->data. */
        extern int _sock_lookup_listen_fd(int sock_fd); /* in glibc */
-       extern int _sock_get_listen_fd(int sock_fd);
-       if (_sock_lookup_listen_fd(fd) >= 0) {
-               errno = EEXIST;
-               return -1;
-       }
-       sock_listen_fd = _sock_get_listen_fd(fd);
+
+       sock_listen_fd = _sock_lookup_listen_fd(fd);
        if (sock_listen_fd >= 0)
                fd = sock_listen_fd;
        ceq_ev = ep_get_ceq_ev(ep, fd);
@@ -350,7 +329,6 @@ static int __epoll_ctl_add(struct epoll_ctlr *ep, int fd,
        ep_fd->filter = filter;
        ep_fd->ep_event = *event;
        ep_fd->ep_event.events |= EPOLLHUP;
-       ep_fd->sock_listen_fd = sock_listen_fd;
        ceq_ev->user_data = (uint64_t)ep_fd;
        return 0;
 }
@@ -386,11 +364,6 @@ static int __epoll_ctl_del(struct epoll_ctlr *ep, int fd,
         * has already closed and the kernel removed the tap. */
        sys_tap_fds(&tap_req, 1);
        ceq_ev->user_data = 0;
-       assert(ep_fd->sock_listen_fd == sock_listen_fd);
-       if (ep_fd->sock_listen_fd >= 0) {
-               assert(ep_fd->sock_listen_fd == sock_listen_fd);
-               close(ep_fd->sock_listen_fd);
-       }
        free(ep_fd);
        return 0;
 }