[vlc-commits] input: add vlc_read_i11e(v) and vlc_write_i11e(v) helpers

Rémi Denis-Courmont git at videolan.org
Wed Jul 1 18:22:11 CEST 2015


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Tue Jun 30 23:52:51 2015 +0300| [d71bd09fdfe9a6aa47a859852ae3365525e9102b] | committer: Rémi Denis-Courmont

input: add vlc_read_i11e(v) and vlc_write_i11e(v) helpers

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=d71bd09fdfe9a6aa47a859852ae3365525e9102b
---

 include/vlc_interrupt.h |    6 ++++
 src/libvlccore.sym      |    4 +++
 src/misc/interrupt.c    |   92 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 102 insertions(+)

diff --git a/include/vlc_interrupt.h b/include/vlc_interrupt.h
index fedbcd8..99f11df 100644
--- a/include/vlc_interrupt.h
+++ b/include/vlc_interrupt.h
@@ -28,6 +28,7 @@
 # include <vlc_threads.h>
 
 struct pollfd;
+struct iovec;
 
 /**
  * @defgroup interrupt Interruptible sleep
@@ -71,6 +72,11 @@ VLC_API int vlc_sem_wait_i11e(vlc_sem_t *);
  */
 VLC_API int vlc_poll_i11e(struct pollfd *, unsigned, int);
 
+VLC_API ssize_t vlc_readv_i11e(int fd, struct iovec *, int);
+VLC_API ssize_t vlc_writev_i11e(int fd, const struct iovec *, int);
+VLC_API ssize_t vlc_read_i11e(int fd, void *, size_t);
+VLC_API ssize_t vlc_write_i11e(int fd, const void *, size_t);
+
 /**
  * @}
  * @defgroup interrupt_context Interrupt context signaling and manipulation
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 7f10d51..0a9cac2 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -540,6 +540,10 @@ vlc_iconv
 vlc_iconv_close
 vlc_iconv_open
 vlc_poll_i11e
+vlc_read_i11e
+vlc_readv_i11e
+vlc_write_i11e
+vlc_writev_i11e
 vlc_sem_wait_i11e
 vlc_interrupt_create
 vlc_interrupt_destroy
diff --git a/src/misc/interrupt.c b/src/misc/interrupt.c
index cefcf9c..5017a36 100644
--- a/src/misc/interrupt.c
+++ b/src/misc/interrupt.c
@@ -360,6 +360,75 @@ int vlc_poll_i11e(struct pollfd *fds, unsigned nfds, int timeout)
     return ret;
 }
 
+# include <fcntl.h>
+# include <sys/uio.h>
+
+/* There are currently no ways to atomically force a non-blocking read or write
+ * operations. Even for sockets, the MSG_DONTWAIT flag is non-standard.
+ *
+ * So in the event that more than one thread tries to read or write on the same
+ * file at the same time, there is a race condition where these functions might
+ * block inspite of an interruption. This should never happen in practice.
+ */
+
+/**
+ * Wrapper for readv() that returns the EINTR error upon VLC I/O interruption.
+ * @warning This function ignores the non-blocking file flag.
+ */
+ssize_t vlc_readv_i11e(int fd, struct iovec *iov, int count)
+{
+    struct pollfd ufd;
+
+    ufd.fd = fd;
+    ufd.events = POLLIN;
+
+    if (vlc_poll_i11e(&ufd, 1, -1) < 0)
+        return -1;
+    return readv(fd, iov, count);
+}
+
+/**
+ * Wrapper for writev() that returns the EINTR error upon VLC I/O interruption.
+ *
+ * @note Like writev(), once some but not all bytes are written, the function
+ * might wait for write completion, regardless of signals and interruptions.
+ * @warning This function ignores the non-blocking file flag.
+ */
+ssize_t vlc_writev_i11e(int fd, const struct iovec *iov, int count)
+{
+    struct pollfd ufd;
+
+    ufd.fd = fd;
+    ufd.events = POLLOUT;
+
+    if (vlc_poll_i11e(&ufd, 1, -1) < 0)
+        return -1;
+    return writev(fd, iov, count);
+}
+
+/**
+ * Wrapper for read() that returns the EINTR error upon VLC I/O interruption.
+ * @warning This function ignores the non-blocking file flag.
+ */
+ssize_t vlc_read_i11e(int fd, void *buf, size_t count)
+{
+    struct iovec iov = { buf, count };
+    return vlc_readv_i11e(fd, &iov, 1);
+}
+
+/**
+ * Wrapper for write() that returns the EINTR error upon VLC I/O interruption.
+ *
+ * @note Like write(), once some but not all bytes are written, the function
+ * might wait for write completion, regardless of signals and interruptions.
+ * @warning This function ignores the non-blocking file flag.
+ */
+ssize_t vlc_write_i11e(int fd, const void *buf, size_t count)
+{
+    struct iovec iov = { (void *)buf, count };
+    return writev(fd, &iov, 1);
+}
+
 #else /* _WIN32 */
 
 static void CALLBACK vlc_poll_i11e_wake_self(ULONG_PTR data)
@@ -422,4 +491,27 @@ out:
     CloseHandle(th);
     return ret;
 }
+
+ssize_t vlc_readv_i11e(int fd, struct iovec *iov, int count)
+{
+    (void) fd; (void) iov; (void) count;
+    vlc_assert_unreachable();
+}
+
+ssize_t vlc_writev_i11e(int fd, const struct iovec *iov, int count)
+{
+    (void) fd; (void) iov; (void) count;
+    vlc_assert_unreachable();
+}
+
+ssize_t vlc_read_i11e(int fd, void *buf, size_t count)
+{
+    return read(fd, buf, count);
+}
+
+ssize_t vlc_write_i11e(int fd, const void *buf, size_t count)
+{
+    return write(fd, buf, count);
+}
+
 #endif



More information about the vlc-commits mailing list