summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorratchov <ratchov@openbsd.org>2012-10-27 12:08:25 +0000
committerratchov <ratchov@openbsd.org>2012-10-27 12:08:25 +0000
commitcfb56cbff173f3acce85bcb8b944782577c26f37 (patch)
tree5ccd935817ffd58263158faf509abe96ab80b786
parentcrank SIO_MAXNFDS (diff)
downloadwireguard-openbsd-cfb56cbff173f3acce85bcb8b944782577c26f37.tar.xz
wireguard-openbsd-cfb56cbff173f3acce85bcb8b944782577c26f37.zip
make midi code use non-blocking i/o as does audio code, in order
to make both look similar
-rw-r--r--lib/libsndio/mio.c79
-rw-r--r--lib/libsndio/mio_aucat.c15
-rw-r--r--lib/libsndio/mio_priv.h5
-rw-r--r--lib/libsndio/mio_rmidi.c16
4 files changed, 101 insertions, 14 deletions
diff --git a/lib/libsndio/mio.c b/lib/libsndio/mio.c
index 8dc0823a930..0f130dbe392 100644
--- a/lib/libsndio/mio.c
+++ b/lib/libsndio/mio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mio.c,v 1.15 2012/05/23 19:25:11 ratchov Exp $ */
+/* $OpenBSD: mio.c,v 1.16 2012/10/27 12:08:25 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -61,8 +61,9 @@ mio_open(const char *str, unsigned int mode, int nbio)
return mio_aucat_open(p, mode, nbio, 0);
if ((p = sndio_parsetype(str, "midithru")) != NULL)
return mio_aucat_open(p, mode, nbio, 1);
- if ((p = sndio_parsetype(str, "rmidi")) != NULL)
+ if ((p = sndio_parsetype(str, "rmidi")) != NULL) {
return mio_rmidi_open(p, mode, nbio);
+ }
DPRINTF("mio_open: %s: unknown device type\n", str);
return NULL;
}
@@ -83,9 +84,46 @@ mio_close(struct mio_hdl *hdl)
hdl->ops->close(hdl);
}
+static int
+mio_psleep(struct mio_hdl *hdl, int event)
+{
+ struct pollfd pfd[MIO_MAXNFDS];
+ int revents;
+ int nfds;
+
+ nfds = mio_nfds(hdl);
+ if (nfds > MIO_MAXNFDS) {
+ DPRINTF("mio_psleep: %d: too many descriptors\n", nfds);
+ hdl->eof = 1;
+ return 0;
+ }
+ for (;;) {
+ nfds = mio_pollfd(hdl, pfd, event);
+ while (poll(pfd, nfds, -1) < 0) {
+ if (errno == EINTR)
+ continue;
+ DPERROR("mio_psleep: poll");
+ hdl->eof = 1;
+ return 0;
+ }
+ revents = mio_revents(hdl, pfd);
+ if (revents & POLLHUP) {
+ DPRINTF("mio_psleep: hang-up\n");
+ return 0;
+ }
+ if (revents & event)
+ break;
+ }
+ return 1;
+}
+
size_t
mio_read(struct mio_hdl *hdl, void *buf, size_t len)
{
+ unsigned int n;
+ char *data = buf;
+ size_t todo = len;
+
if (hdl->eof) {
DPRINTF("mio_read: eof\n");
return 0;
@@ -99,12 +137,27 @@ mio_read(struct mio_hdl *hdl, void *buf, size_t len)
DPRINTF("mio_read: zero length read ignored\n");
return 0;
}
- return hdl->ops->read(hdl, buf, len);
+ while (todo > 0) {
+ n = hdl->ops->read(hdl, data, todo);
+ if (n == 0 && hdl->eof)
+ break;
+ data += n;
+ todo -= n;
+ if (n > 0 || hdl->nbio)
+ break;
+ if (!mio_psleep(hdl, POLLIN))
+ break;
+ }
+ return len - todo;
}
size_t
mio_write(struct mio_hdl *hdl, const void *buf, size_t len)
{
+ unsigned int n;
+ const unsigned char *data = buf;
+ size_t todo = len;
+
if (hdl->eof) {
DPRINTF("mio_write: eof\n");
return 0;
@@ -118,13 +171,29 @@ mio_write(struct mio_hdl *hdl, const void *buf, size_t len)
DPRINTF("mio_write: zero length write ignored\n");
return 0;
}
- return hdl->ops->write(hdl, buf, len);
+ if (todo == 0) {
+ DPRINTF("mio_write: zero length write ignored\n");
+ return 0;
+ }
+ while (todo > 0) {
+ n = hdl->ops->write(hdl, data, todo);
+ if (n == 0) {
+ if (hdl->nbio || hdl->eof)
+ break;
+ if (!mio_psleep(hdl, POLLOUT))
+ break;
+ continue;
+ }
+ data += n;
+ todo -= n;
+ }
+ return len - todo;
}
int
mio_nfds(struct mio_hdl *hdl)
{
- return 1;
+ return hdl->ops->nfds(hdl);
}
int
diff --git a/lib/libsndio/mio_aucat.c b/lib/libsndio/mio_aucat.c
index 15b073c0491..6f5caa8fbba 100644
--- a/lib/libsndio/mio_aucat.c
+++ b/lib/libsndio/mio_aucat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mio_aucat.c,v 1.7 2012/04/11 06:05:43 ratchov Exp $ */
+/* $OpenBSD: mio_aucat.c,v 1.8 2012/10/27 12:08:25 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -18,6 +18,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
+#include <netinet/in.h>
#include <errno.h>
#include <fcntl.h>
@@ -40,6 +41,7 @@ struct mio_aucat_hdl {
static void mio_aucat_close(struct mio_hdl *);
static size_t mio_aucat_read(struct mio_hdl *, void *, size_t);
static size_t mio_aucat_write(struct mio_hdl *, const void *, size_t);
+static int mio_aucat_nfds(struct mio_hdl *);
static int mio_aucat_pollfd(struct mio_hdl *, struct pollfd *, int);
static int mio_aucat_revents(struct mio_hdl *, struct pollfd *);
@@ -47,8 +49,9 @@ static struct mio_ops mio_aucat_ops = {
mio_aucat_close,
mio_aucat_write,
mio_aucat_read,
+ mio_aucat_nfds,
mio_aucat_pollfd,
- mio_aucat_revents,
+ mio_aucat_revents
};
struct mio_hdl *
@@ -63,7 +66,7 @@ mio_aucat_open(const char *str, unsigned int mode,
if (!aucat_open(&hdl->aucat, str, mode, type))
goto bad;
mio_create(&hdl->mio, &mio_aucat_ops, mode, nbio);
- if (!aucat_setfl(&hdl->aucat, nbio, &hdl->mio.eof))
+ if (!aucat_setfl(&hdl->aucat, 1, &hdl->mio.eof))
goto bad;
return (struct mio_hdl *)hdl;
bad:
@@ -103,6 +106,12 @@ mio_aucat_write(struct mio_hdl *sh, const void *buf, size_t len)
}
static int
+mio_aucat_nfds(struct mio_hdl *sh)
+{
+ return 1;
+}
+
+static int
mio_aucat_pollfd(struct mio_hdl *sh, struct pollfd *pfd, int events)
{
struct mio_aucat_hdl *hdl = (struct mio_aucat_hdl *)sh;
diff --git a/lib/libsndio/mio_priv.h b/lib/libsndio/mio_priv.h
index 60efc2b7733..0e1b6ba530c 100644
--- a/lib/libsndio/mio_priv.h
+++ b/lib/libsndio/mio_priv.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mio_priv.h,v 1.8 2011/11/15 08:05:22 ratchov Exp $ */
+/* $OpenBSD: mio_priv.h,v 1.9 2012/10/27 12:08:25 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -20,6 +20,8 @@
#include <sys/param.h>
#include "sndio.h"
+#define MIO_MAXNFDS 16
+
/*
* private ``handle'' structure
*/
@@ -37,6 +39,7 @@ struct mio_ops {
void (*close)(struct mio_hdl *);
size_t (*write)(struct mio_hdl *, const void *, size_t);
size_t (*read)(struct mio_hdl *, void *, size_t);
+ int (*nfds)(struct mio_hdl *);
int (*pollfd)(struct mio_hdl *, struct pollfd *, int);
int (*revents)(struct mio_hdl *, struct pollfd *);
};
diff --git a/lib/libsndio/mio_rmidi.c b/lib/libsndio/mio_rmidi.c
index c66ca21b75a..c82425201b7 100644
--- a/lib/libsndio/mio_rmidi.c
+++ b/lib/libsndio/mio_rmidi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mio_rmidi.c,v 1.11 2012/04/11 06:05:43 ratchov Exp $ */
+/* $OpenBSD: mio_rmidi.c,v 1.12 2012/10/27 12:08:25 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -38,6 +38,7 @@ struct mio_rmidi_hdl {
static void mio_rmidi_close(struct mio_hdl *);
static size_t mio_rmidi_read(struct mio_hdl *, void *, size_t);
static size_t mio_rmidi_write(struct mio_hdl *, const void *, size_t);
+static int mio_rmidi_nfds(struct mio_hdl *);
static int mio_rmidi_pollfd(struct mio_hdl *, struct pollfd *, int);
static int mio_rmidi_revents(struct mio_hdl *, struct pollfd *);
@@ -45,8 +46,9 @@ static struct mio_ops mio_rmidi_ops = {
mio_rmidi_close,
mio_rmidi_write,
mio_rmidi_read,
+ mio_rmidi_nfds,
mio_rmidi_pollfd,
- mio_rmidi_revents,
+ mio_rmidi_revents
};
struct mio_hdl *
@@ -75,9 +77,7 @@ mio_rmidi_open(const char *str, unsigned int mode, int nbio)
flags = O_RDWR;
else
flags = (mode & MIO_OUT) ? O_WRONLY : O_RDONLY;
- if (nbio)
- flags |= O_NONBLOCK;
- while ((fd = open(path, flags)) < 0) {
+ while ((fd = open(path, flags | O_NONBLOCK)) < 0) {
if (errno == EINTR)
continue;
DPERROR(path);
@@ -151,6 +151,12 @@ mio_rmidi_write(struct mio_hdl *sh, const void *buf, size_t len)
}
static int
+mio_rmidi_nfds(struct mio_hdl *sh)
+{
+ return 1;
+}
+
+static int
mio_rmidi_pollfd(struct mio_hdl *sh, struct pollfd *pfd, int events)
{
struct mio_rmidi_hdl *hdl = (struct mio_rmidi_hdl *)sh;