Decouple the signalling into a struct IOMuxSignaller
This commit is contained in:
@@ -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
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user