From b83d2fb2cf5a12115e0d57fa8f191d1ba465e419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Tue, 24 Dec 2013 01:51:40 +0100 Subject: [PATCH] Decouple the signalling into a struct IOMuxSignaller --- include/ucore/iomux_waker.h | 11 +++++++++-- src/iomux_waker.c | 30 ++++++++++++++++-------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/include/ucore/iomux_waker.h b/include/ucore/iomux_waker.h index e5e6c8d..bf382e2 100644 --- a/include/ucore/iomux_waker.h +++ b/include/ucore/iomux_waker.h @@ -10,6 +10,11 @@ extern "C" { struct IOMuxWaker; typedef void (*uc_waker_cb)(struct IOMuxWaker *wk); +/** Usef for signalling an IOMux */ +struct IOMuxSignaller { + int fd; +}; + /** These are primitives to wake up an IOMux. * An IOMux event loop can be woken up from e.g. an unix signal handler * or another thread. The IOMuxWaker itself is not thread safe, it's members @@ -22,11 +27,11 @@ typedef void (*uc_waker_cb)(struct IOMuxWaker *wk); */ struct IOMuxWaker { //private fields - int fds[2]; struct IOMuxFD read_fd; uc_waker_cb wake_cb; //public fields + struct IOMuxSignaller signaller; struct IOMux *mux; void *cookie; }; @@ -47,6 +52,8 @@ int uc_iomux_waker_init(struct IOMux *mux, struct IOMuxWaker *wk, uc_waker_cb cb * Care must be taken so the IOMuxWaker is destroyed * without race conditions with a thread that wants to _signal the * waker. + * The embedded IOMuxSignaller of the IOMuxWaker can be used + * by someone else in the uc_iomux_waker_signal() function * * @param wk * @return 0 on success, errno on failure (Things are seriously @@ -63,7 +70,7 @@ int uc_iomux_waker_destroy(struct IOMuxWaker *wk); * @return 0 on success, errno on failure (Things are seriously * wrong if this fails) */ -int uc_iomux_waker_signal(struct IOMuxWaker *wk); +int uc_iomux_waker_signal(struct IOMuxSignaller *signaller); #ifdef __cplusplus } diff --git a/src/iomux_waker.c b/src/iomux_waker.c index 172b1fa..a7c517b 100644 --- a/src/iomux_waker.c +++ b/src/iomux_waker.c @@ -6,7 +6,7 @@ static void uc_waker_pipe_cb(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event) { - char buf[259]; + char buf[256]; struct IOMuxWaker *wk; int rc; @@ -32,13 +32,13 @@ static void uc_waker_pipe_cb(struct IOMux *mux, struct IOMuxFD *fd, unsigned int wk->wake_cb(wk); } -static int uc_install_wake_handler(struct IOMuxWaker *wk) +static int uc_install_wake_handler(struct IOMuxWaker *wk, int rfd) { struct IOMuxFD *fd = &wk->read_fd; memset(fd, 0, sizeof *fd); - fd->fd = wk->fds[0]; + fd->fd = rfd; fd->callback = uc_waker_pipe_cb; fd->cookie_ptr = wk; fd->what = MUX_EV_READ; @@ -49,28 +49,30 @@ static int uc_install_wake_handler(struct IOMuxWaker *wk) int uc_iomux_waker_init(struct IOMux *mux, struct IOMuxWaker *wk, uc_waker_cb cb) { int rc; + int pfds[2]; assert(wk != NULL); assert(cb != NULL); memset(wk, 0 , sizeof *wk); - rc = pipe(wk->fds); + rc = pipe(pfds); if (rc != 0) { return errno; } wk->mux = mux; wk->wake_cb = cb; + wk->signaller.fd = pfds[1]; - if (uc_install_wake_handler(wk) == 0) { + if (uc_install_wake_handler(wk, pfds[0]) == 0) { return 0; } else { int saved_errno; saved_errno = errno; - close(wk->fds[0]); - close(wk->fds[1]); + close(pfds[0]); + close(pfds[1]); return saved_errno; } @@ -82,30 +84,30 @@ int uc_iomux_waker_destroy(struct IOMuxWaker *wk) assert(wk != NULL); - close(wk->fds[0]); - close(wk->fds[1]); - rc = iomux_unregister_fd(wk->mux, &wk->read_fd); assert(rc == 0); + close(wk->signaller.fd); + close(wk->read_fd.fd); + wk->mux = NULL; wk->wake_cb = NULL; - wk->fds[0] = wk->fds[1] = -1; + wk->signaller.fd = -1; assert(rc == 0); return rc; } -int uc_iomux_waker_signal(struct IOMuxWaker *wk) +int uc_iomux_waker_signal(struct IOMuxSignaller *signaller) { int rc; static const char x = 'X'; - assert(wk != NULL); + assert(signaller != NULL); do { - rc = write(wk->fds[1], &x, 1); + rc = write(signaller->fd, &x, 1); } while (rc == -1 && errno == EINTR); //if we would have blocked, the pipe is already