Decouple the signalling into a struct IOMuxSignaller

This commit is contained in:
Nils O. Selåsdal
2013-12-24 01:51:40 +01:00
parent 277900b08e
commit b83d2fb2cf
2 changed files with 25 additions and 16 deletions
+9 -2
View File
@@ -10,6 +10,11 @@ extern "C" {
struct IOMuxWaker; struct IOMuxWaker;
typedef void (*uc_waker_cb)(struct IOMuxWaker *wk); 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. /** These are primitives to wake up an IOMux.
* An IOMux event loop can be woken up from e.g. an unix signal handler * 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 * 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 { struct IOMuxWaker {
//private fields //private fields
int fds[2];
struct IOMuxFD read_fd; struct IOMuxFD read_fd;
uc_waker_cb wake_cb; uc_waker_cb wake_cb;
//public fields //public fields
struct IOMuxSignaller signaller;
struct IOMux *mux; struct IOMux *mux;
void *cookie; 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 * Care must be taken so the IOMuxWaker is destroyed
* without race conditions with a thread that wants to _signal the * without race conditions with a thread that wants to _signal the
* waker. * waker.
* The embedded IOMuxSignaller of the IOMuxWaker can be used
* by someone else in the uc_iomux_waker_signal() function
* *
* @param wk * @param wk
* @return 0 on success, errno on failure (Things are seriously * @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 * @return 0 on success, errno on failure (Things are seriously
* wrong if this fails) * wrong if this fails)
*/ */
int uc_iomux_waker_signal(struct IOMuxWaker *wk); int uc_iomux_waker_signal(struct IOMuxSignaller *signaller);
#ifdef __cplusplus #ifdef __cplusplus
} }
+16 -14
View File
@@ -6,7 +6,7 @@
static void uc_waker_pipe_cb(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event) static void uc_waker_pipe_cb(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event)
{ {
char buf[259]; char buf[256];
struct IOMuxWaker *wk; struct IOMuxWaker *wk;
int rc; int rc;
@@ -32,13 +32,13 @@ static void uc_waker_pipe_cb(struct IOMux *mux, struct IOMuxFD *fd, unsigned int
wk->wake_cb(wk); 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; struct IOMuxFD *fd = &wk->read_fd;
memset(fd, 0, sizeof *fd); memset(fd, 0, sizeof *fd);
fd->fd = wk->fds[0]; fd->fd = rfd;
fd->callback = uc_waker_pipe_cb; fd->callback = uc_waker_pipe_cb;
fd->cookie_ptr = wk; fd->cookie_ptr = wk;
fd->what = MUX_EV_READ; 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 uc_iomux_waker_init(struct IOMux *mux, struct IOMuxWaker *wk, uc_waker_cb cb)
{ {
int rc; int rc;
int pfds[2];
assert(wk != NULL); assert(wk != NULL);
assert(cb != NULL); assert(cb != NULL);
memset(wk, 0 , sizeof *wk); memset(wk, 0 , sizeof *wk);
rc = pipe(wk->fds); rc = pipe(pfds);
if (rc != 0) { if (rc != 0) {
return errno; return errno;
} }
wk->mux = mux; wk->mux = mux;
wk->wake_cb = cb; 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; return 0;
} else { } else {
int saved_errno; int saved_errno;
saved_errno = errno; saved_errno = errno;
close(wk->fds[0]); close(pfds[0]);
close(wk->fds[1]); close(pfds[1]);
return saved_errno; return saved_errno;
} }
@@ -82,30 +84,30 @@ int uc_iomux_waker_destroy(struct IOMuxWaker *wk)
assert(wk != NULL); assert(wk != NULL);
close(wk->fds[0]);
close(wk->fds[1]);
rc = iomux_unregister_fd(wk->mux, &wk->read_fd); rc = iomux_unregister_fd(wk->mux, &wk->read_fd);
assert(rc == 0); assert(rc == 0);
close(wk->signaller.fd);
close(wk->read_fd.fd);
wk->mux = NULL; wk->mux = NULL;
wk->wake_cb = NULL; wk->wake_cb = NULL;
wk->fds[0] = wk->fds[1] = -1; wk->signaller.fd = -1;
assert(rc == 0); assert(rc == 0);
return rc; return rc;
} }
int uc_iomux_waker_signal(struct IOMuxWaker *wk) int uc_iomux_waker_signal(struct IOMuxSignaller *signaller)
{ {
int rc; int rc;
static const char x = 'X'; static const char x = 'X';
assert(wk != NULL); assert(signaller != NULL);
do { do {
rc = write(wk->fds[1], &x, 1); rc = write(signaller->fd, &x, 1);
} while (rc == -1 && errno == EINTR); } while (rc == -1 && errno == EINTR);
//if we would have blocked, the pipe is already //if we would have blocked, the pipe is already