summaryrefslogtreecommitdiffstats
path: root/osdep
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2017-12-09 09:41:09 -0500
committerJan Ekström <jeebjp@gmail.com>2017-12-09 21:11:46 +0200
commitba418132cd04865d444f4da2b5553e4d83b18138 (patch)
tree5e60f610cc1c1b3ed029da0643c9bb51e63001f9 /osdep
parent1d7a746505a2a5ec0392e0c8a6c1ddd0c7133baa (diff)
downloadmpv-ba418132cd04865d444f4da2b5553e4d83b18138.tar.bz2
mpv-ba418132cd04865d444f4da2b5553e4d83b18138.tar.xz
osdep: add poll shim for macOS
This implements a poll-compatible interface, backed by select on macOS, suitable for polling on device files - which are not supported by macOS's implementation of poll. This is a (long-standing) bug in macOS, so hopefully we can eventually remove this shim.
Diffstat (limited to 'osdep')
-rw-r--r--osdep/polldev.c75
-rw-r--r--osdep/polldev.h7
2 files changed, 82 insertions, 0 deletions
diff --git a/osdep/polldev.c b/osdep/polldev.c
new file mode 100644
index 0000000000..ba2df2a2e3
--- /dev/null
+++ b/osdep/polldev.c
@@ -0,0 +1,75 @@
+/*
+ * poll shim that supports device files on macOS.
+ *
+ * This file is part of mpv.
+ *
+ * mpv is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * mpv is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with mpv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <poll.h>
+#include <sys/select.h>
+#include <stdio.h>
+
+#include "osdep/polldev.h"
+
+int polldev(struct pollfd fds[], nfds_t nfds, int timeout) {
+#ifdef __APPLE__
+ int maxfd = 0;
+ fd_set readfds, writefds, errorfds;
+ FD_ZERO(&readfds);
+ FD_ZERO(&writefds);
+ FD_ZERO(&errorfds);
+ for (size_t i = 0; i < nfds; ++i) {
+ struct pollfd *fd = &fds[i];
+ if (fd->fd > maxfd) {
+ maxfd = fd->fd;
+ }
+ if ((fd->events & POLLIN)) {
+ FD_SET(fd->fd, &readfds);
+ }
+ if ((fd->events & POLLOUT)) {
+ FD_SET(fd->fd, &writefds);
+ }
+ if ((fd->events & POLLERR)) {
+ FD_SET(fd->fd, &errorfds);
+ }
+ }
+ struct timeval _timeout = {
+ .tv_sec = timeout / 1000,
+ .tv_usec = (timeout % 1000) * 1000
+ };
+ int n = select(maxfd + 1, &readfds, &writefds, &errorfds,
+ timeout != -1 ? &_timeout : NULL);
+ if (n < 0) {
+ return n;
+ }
+ for (size_t i = 0; i < nfds; ++i) {
+ struct pollfd *fd = &fds[i];
+ fd->revents = 0;
+ if (FD_ISSET(fd->fd, &readfds)) {
+ fd->revents |= POLLIN;
+ }
+ if (FD_ISSET(fd->fd, &writefds)) {
+ fd->revents |= POLLOUT;
+ }
+ if (FD_ISSET(fd->fd, &errorfds)) {
+ fd->revents |= POLLERR;
+ }
+ }
+ return n;
+#else
+ return poll(fds, nfds, timeout);
+#endif
+}
diff --git a/osdep/polldev.h b/osdep/polldev.h
new file mode 100644
index 0000000000..50b6db29bc
--- /dev/null
+++ b/osdep/polldev.h
@@ -0,0 +1,7 @@
+#pragma once
+
+#include <poll.h>
+
+// Behaves like poll(3) but works for device files on macOS.
+// Only supports POLLIN, POLLOUT, and POLLERR.
+int polldev(struct pollfd fds[], nfds_t nfds, int timeout);