Instead of only opening the listen file on demand and having our user close it (which is a huge mess), we just open it right away and close it when the socket / Rock is closed.
This will help out epoll, which currently will deadlock if it attempts to close a listen_fd while holding its own locks, since epoll itself has a close callback. Rebuild glibc. Signed-off-by: Barret Rhoden <[email protected]> --- .../glibc-2.19-akaros/sysdeps/akaros/listen.c | 2 ++ .../sysdeps/akaros/plan9_sockets.c | 28 +++++++++++++--------- .../sysdeps/akaros/plan9_sockets.h | 2 ++ 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/listen.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/listen.c index f3837acde288..49b2ddec2599 100644 --- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/listen.c +++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/listen.c @@ -67,6 +67,8 @@ int __listen(int fd, int backlog) } close(cfd); r->is_listener = TRUE; + if (_rock_open_listen_fd(r) < 0) + return -1; return 0; case PF_UNIX: if (r->other < 0) { diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/plan9_sockets.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/plan9_sockets.c index 924551cf40af..3729c6dd9527 100644 --- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/plan9_sockets.c +++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/plan9_sockets.c @@ -189,6 +189,12 @@ Rock *_sock_newrock(int fd) void _sock_fd_closed(int fd) { + Rock *r = _sock_findrock(fd, 0); + + if (!r) + return; + if (r->is_listener) + close(r->listen_fd); } /* For a ctlfd and a few other settings, it opens and returns the corresponding @@ -287,22 +293,23 @@ int _sock_get_opts(int type) return type & (SOCK_NONBLOCK | SOCK_CLOEXEC); } -/* Used by user/iplib (e.g. epoll). Opens and returns the FD for the - * conversation's listen fd, which the caller needs to close. Returns -1 if the - * FD is not a listener. */ +/* Temp dummy, for compilation */ int _sock_get_listen_fd(int sock_fd) { + return -1; +} + +/* Opens the FD for "listen", and attaches it to the Rock. When the dfd (and + * thus the Rock) closes, we'll close the listen file too. Returns the FD on + * success, -1 on error. */ +int _rock_open_listen_fd(Rock *r) +{ char listen_file[Ctlsize + 3]; char *x, *last_ctl; - Rock *r = _sock_findrock(sock_fd, 0); int ret; - if (!r) - return -1; if (!r->is_listener) return -1; - /* We want an FD for the "listen" file. This is for epoll. We - * could optimize and only do this on demand, but whatever. */ strncpy(listen_file, r->ctl, sizeof(listen_file)); /* We want the conversation directory. We can find the last "ctl" * in the CTL name (they could have mounted at /ctlfoo/net/) */ @@ -324,9 +331,8 @@ int _sock_get_listen_fd(int sock_fd) return ret; } -/* Used by user/iplib (e.g. epoll). Looks up a previously opened FD for the - * listen file for this conversation. Returns -1 if the FD is not a listener - * with an already-opened listen FD. */ +/* Used by user/iplib (e.g. epoll). Looks up the FD listen file for this + * conversation. Returns -1 if the FD is not a listener. */ int _sock_lookup_listen_fd(int sock_fd) { Rock *r = _sock_findrock(sock_fd, 0); diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/plan9_sockets.h b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/plan9_sockets.h index d0a62065fcab..253622431882 100644 --- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/plan9_sockets.h +++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/plan9_sockets.h @@ -72,6 +72,8 @@ extern void _sock_ingetaddr(Rock *, struct sockaddr_in *, socklen_t *, const char *); extern int _sock_strip_opts(int type); extern int _sock_get_opts(int type); +extern int _rock_open_listen_fd(Rock *r); +extern int _sock_lookup_listen_fd(int sock_fd); extern void _syserrno(void); -- 2.6.0.rc2.230.g3dd15c0 -- You received this message because you are subscribed to the Google Groups "Akaros" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. For more options, visit https://groups.google.com/d/optout.
