]> git.sesse.net Git - vlc/blobdiff - src/network/io.c
Revert "Include vlc_common.h to get VLC_UNUSED()"
[vlc] / src / network / io.c
index d8e21d31a8b6875406a16eeea339b6356c3e11e9..905f605cb8d4c026875481a0f97385e5bd819fef 100644 (file)
  * Preamble
  *****************************************************************************/
 
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
 #include <vlc/vlc.h>
 
 #include <stdlib.h>
 # define EAFNOSUPPORT WSAEAFNOSUPPORT
 #endif
 
+#ifdef HAVE_LINUX_DCCP_H
+/* TODO: use glibc instead of linux-kernel headers */
+# include <linux/dccp.h>
+# define SOL_DCCP 269
+#endif
+
 extern int rootwrap_bind (int family, int socktype, int protocol,
                           const struct sockaddr *addr, size_t alen);
 
@@ -114,6 +124,16 @@ int net_Socket (vlc_object_t *p_this, int family, int socktype,
                     &(int){ PROTECTION_LEVEL_UNRESTRICTED }, sizeof (int));
 #endif
 
+#ifdef DCCP_SOCKOPT_SERVICE
+    char *dccps = var_CreateGetNonEmptyString (p_this, "dccp-service");
+    if (dccps != NULL)
+    {
+        setsockopt (fd, SOL_DCCP, DCCP_SOCKOPT_SERVICE, dccps,
+                    (strlen (dccps) + 3) & ~3);
+        free (dccps);
+    }
+#endif
+
     return fd;
 }
 
@@ -258,7 +278,8 @@ int *net_Listen (vlc_object_t *p_this, const char *psz_host,
  *****************************************************************************
  * Reads from a network socket.
  * If waitall is true, then we repeat until we have read the right amount of
- * data; in that case, a short count means EOF has been reached.
+ * data; in that case, a short count means EOF has been reached or the VLC
+ * object has been signaled.
  *****************************************************************************/
 ssize_t
 __net_Read (vlc_object_t *restrict p_this, int fd, const v_socket_t *vs,
@@ -266,45 +287,24 @@ __net_Read (vlc_object_t *restrict p_this, int fd, const v_socket_t *vs,
 {
     size_t i_total = 0;
     struct pollfd ufd[2] = {
-        { .fd = fd, .events = POLLIN },
-        { .fd = -1, .events = POLLIN },
+        { .fd = fd,                           .events = POLLIN },
+        { .fd = vlc_object_waitpipe (p_this), .events = POLLIN },
     };
 
-    vlc_object_lock (p_this);
-    ufd[1].fd = vlc_object_waitpipe (p_this);
+    if (ufd[1].fd == -1)
+        return -1; /* vlc_object_waitpipe() sets errno */
 
     while (i_buflen > 0)
     {
-        int val;
-
-        if (!vlc_object_alive (p_this))
-        {
-#if defined(WIN32) || defined(UNDER_CE)
-            WSASetLastError (WSAEINTR);
-#else
-            errno = EINTR;
-#endif
-            goto error;
-        }
         ufd[0].revents = ufd[1].revents = 0;
 
-        vlc_object_unlock (p_this);
-        val = poll (ufd, sizeof (ufd) / sizeof (ufd[0]), -1);
-        vlc_object_lock (p_this);
-
-        if (val < 0)
-            goto error;
-
-        if (ufd[1].revents)
+        if (poll (ufd, sizeof (ufd) / sizeof (ufd[0]), -1) < 0)
         {
-            msg_Dbg (p_this, "socket %d polling interrupted", fd);
-            vlc_object_wait (p_this);
-            msg_Dbg (p_this, "socket %d polling restarting", fd);
+            if (errno != EINTR)
+                goto error;
             continue;
         }
 
-        assert (ufd[0].revents);
-
 #ifndef POLLRDHUP /* This is nice but non-portable */
 # define POLLRDHUP 0
 #endif
@@ -315,8 +315,26 @@ __net_Read (vlc_object_t *restrict p_this, int fd, const v_socket_t *vs,
              * bad idea™. */
             if (ufd[0].revents & (POLLERR|POLLNVAL|POLLRDHUP))
                 break;
+            if (ufd[1].revents)
+                break;
+        }
+        else
+        {
+            if (ufd[1].revents)
+            {
+                assert (p_this->b_die);
+                msg_Dbg (p_this, "socket %d polling interrupted", fd);
+#if defined(WIN32) || defined(UNDER_CE)
+                WSASetLastError (WSAEINTR);
+#else
+                errno = EINTR;
+#endif
+                goto error;
+            }
         }
 
+        assert (ufd[0].revents);
+
         ssize_t n;
         if (vs != NULL)
         {
@@ -378,13 +396,10 @@ __net_Read (vlc_object_t *restrict p_this, int fd, const v_socket_t *vs,
             break;
     }
 
-    vlc_object_unlock (p_this);
     return i_total;
 
 error:
     msg_Err (p_this, "Read error: %m");
-
-    vlc_object_unlock (p_this);
     return -1;
 }
 
@@ -394,30 +409,47 @@ ssize_t __net_Write( vlc_object_t *p_this, int fd, const v_socket_t *p_vs,
                      const uint8_t *p_data, size_t i_data )
 {
     size_t i_total = 0;
+    struct pollfd ufd[2] = {
+        { .fd = fd,                           .events = POLLOUT },
+        { .fd = vlc_object_waitpipe (p_this), .events = POLLIN  },
+    };
+
+    if (ufd[1].fd == -1)
+        return -1;
 
     while( i_data > 0 )
     {
-        if( p_this->b_die )
-            break;
+        ssize_t val;
 
-        struct pollfd ufd[1];
-        memset (ufd, 0, sizeof (ufd));
-        ufd[0].fd = fd;
-        ufd[0].events = POLLOUT;
+        ufd[0].revents = ufd[1].revents = 0;
 
-        int val = poll (ufd, 1, 500);
-        switch (val)
+        if (poll (ufd, 1, -1) == -1)
         {
-            case -1:
-               msg_Err (p_this, "Write error: %m");
-               goto out;
-
-            case 0:
-                continue;
+            if (errno != EINTR)
+            {
+                msg_Err (p_this, "Write error: %m");
+                goto error;
+            }
+            continue;
         }
 
-        if ((ufd[0].revents & (POLLERR|POLLNVAL|POLLHUP)) && (i_total > 0))
-            return i_total; // error will be dequeued separately on next call
+        if (i_total > 0)
+        {
+            /* Errors will be dequeued separately, upon next call. */
+            if (ufd[0].revents & (POLLERR|POLLNVAL|POLLHUP))
+                break;
+            if (ufd[1].revents)
+                break;
+        }
+        else
+        {
+            if (ufd[1].revents)
+            {
+                assert (p_this->b_die);
+                errno = EINTR;
+                goto error;
+            }
+        }
 
         if (p_vs != NULL)
             val = p_vs->pf_send (p_vs->p_sys, p_data, i_data);
@@ -439,10 +471,10 @@ ssize_t __net_Write( vlc_object_t *p_this, int fd, const v_socket_t *p_vs,
         i_total += val;
     }
 
-out:
     if ((i_total > 0) || (i_data == 0))
         return i_total;
 
+error:
     return -1;
 }