Akaros has various utilities in userspace that operate on FDs, but those facilities are in the kernel in other OSs. These facilities would like to know when the FD is closed.
Rebuild glibc. Signed-off-by: Barret Rhoden <[email protected]> --- .../glibc-2.19-akaros/sysdeps/akaros/Makefile | 2 ++ .../glibc-2.19-akaros/sysdeps/akaros/Versions | 2 ++ .../glibc-2.19-akaros/sysdeps/akaros/close.c | 14 +++++++--- .../glibc-2.19-akaros/sysdeps/akaros/close_cb.c | 20 +++++++++++++++ .../sysdeps/akaros/sys/close_cb.h | 30 ++++++++++++++++++++++ 5 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/close_cb.c create mode 100644 tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sys/close_cb.h diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/Makefile b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/Makefile index d8f008bfee14..fa44dc5beedc 100644 --- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/Makefile +++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/Makefile @@ -55,8 +55,10 @@ endif # User FDs ifeq ($(subdir),stdlib) sysdep_routines += user_fd +sysdep_routines += close_cb endif sysdep_headers += sys/user_fd.h +sysdep_headers += sys/close_cb.h # Epoll: uses User FDs, implemented in iplib sysdep_headers += sys/epoll.h bits/epoll.h diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/Versions b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/Versions index d2b3cc386de7..03a8fa2507a8 100644 --- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/Versions +++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/Versions @@ -48,6 +48,8 @@ libc { ufd_get_fd; ufd_lookup; + register_close_cb; + _sock_get_listen_fd; _sock_lookup_listen_fd; diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/close.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/close.c index fc9f0dfee659..916471ff6d58 100644 --- a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/close.c +++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/close.c @@ -22,11 +22,19 @@ #include <stddef.h> #include <ros/syscall.h> #include <sys/user_fd.h> +#include <sys/close_cb.h> -/* Write NBYTES of BUF to FD. Return the number written, or -1. */ -int -__close (int fd) +int __close(int fd) { + struct close_cb *cb = close_callbacks; + + /* Another thread could be publishing a new callback to the front of the + * list concurrently. We'll miss that callback. They to handle this, + * usually by making sure their CB is registered before using FDs. */ + while (cb) { + cb->func(fd); + cb = cb->next; + } if (fd >= USER_FD_BASE) return glibc_close_helper(fd); else diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/close_cb.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/close_cb.c new file mode 100644 index 000000000000..19114b7880b4 --- /dev/null +++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/close_cb.c @@ -0,0 +1,20 @@ +/* Copyright (c) 2015 Google Inc. + * Barret Rhoden <[email protected]> + * See LICENSE for details. + * + * close() callbacks. See sys/close_cb.h. */ + +#include <sys/close_cb.h> +#include <ros/common.h> + +struct close_cb *close_callbacks; + +void register_close_cb(struct close_cb *cb) +{ + struct close_cb *old; + + do { + old = ACCESS_ONCE(close_callbacks); + cb->next = old; + } while (!__sync_bool_compare_and_swap(&close_callbacks, old, cb)); +} diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sys/close_cb.h b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sys/close_cb.h new file mode 100644 index 000000000000..784a97793290 --- /dev/null +++ b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/sys/close_cb.h @@ -0,0 +1,30 @@ +/* Copyright (c) 2015 Google Inc. + * Barret Rhoden <[email protected]> + * See LICENSE for details. + * + * close() callbacks. + * + * Akaros has various utilities in userspace that operate on FDs, but those + * facilities are in the kernel in other OSs. Examples include epoll and the + * Rocks (socket layer). So far, these are only for compatibility. + * + * These facilities would like to know when the FD is closed. In lieu of + * encoding the callback info in the FD, close() will call all of the registered + * callbacks for every FD that closes. That's not ideal, so these facilities + * should only register their FD if a program actually uses the facility. + * + * To register a cb, do your own allocation of a close_cb, fill in func, then + * call register_close_cb. You cannot remove your CB. Concurrent calls to + * close() may or may not run your callback. Do not hand out an FD to a user + * until you have registered your CB. */ + +#pragma once + +struct close_cb { + struct close_cb *next; + void (*func)(int fd); +}; + +extern struct close_cb *close_callbacks; /* for use within glibc */ + +void register_close_cb(struct close_cb *cb); -- 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.
