]> git.sesse.net Git - vlc/blobdiff - src/network/io.c
fix testapi test: libvlc_instance_(play|pause|stop) are asynchronous, so wait for...
[vlc] / src / network / io.c
index 326131abee27c2c2ba8c9dfb55308f4e7e99eebc..16094f4ac56974656440614ffb3b083717843139 100644 (file)
 # 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);
 
@@ -118,6 +124,19 @@ int net_Socket (vlc_object_t *p_this, int family, int socktype,
                     &(int){ PROTECTION_LEVEL_UNRESTRICTED }, sizeof (int));
 #endif
 
+#ifdef DCCP_SOCKOPT_SERVICE
+    if (socktype == SOL_DCCP)
+    {
+        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;
 }
 
@@ -280,32 +299,15 @@ __net_Read (vlc_object_t *restrict p_this, int fd, const v_socket_t *vs,
 
     while (i_buflen > 0)
     {
-        int val;
-
         ufd[0].revents = ufd[1].revents = 0;
 
-        val = poll (ufd, sizeof (ufd) / sizeof (ufd[0]), -1);
-
-        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);
-            if (i_total == 0)
-            {
-#if defined(WIN32) || defined(UNDER_CE)
-                WSASetLastError (WSAEINTR);
-#else
-                errno = EINTR;
-#endif
+            if (errno != EINTR)
                 goto error;
-            }
-            break;
+            continue;
         }
 
-        assert (ufd[0].revents);
-
 #ifndef POLLRDHUP /* This is nice but non-portable */
 # define POLLRDHUP 0
 #endif
@@ -316,7 +318,25 @@ __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 silent;
+            }
+        }
+
+        assert (ufd[0].revents);
 
         ssize_t n;
         if (vs != NULL)
@@ -383,6 +403,7 @@ __net_Read (vlc_object_t *restrict p_this, int fd, const v_socket_t *vs,
 
 error:
     msg_Err (p_this, "Read error: %m");
+silent:
     return -1;
 }
 
@@ -411,13 +432,28 @@ ssize_t __net_Write( vlc_object_t *p_this, int fd, const v_socket_t *p_vs,
             if (errno != EINTR)
             {
                 msg_Err (p_this, "Write error: %m");
-                goto out;
+                goto error;
             }
             continue;
         }
 
-        if ((ufd[0].revents & (POLLERR|POLLNVAL|POLLHUP)) && (i_total > 0))
-            break; // 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 +475,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;
 }
 
@@ -535,7 +571,7 @@ int inet_pton(int af, const char *src, void *dst)
     char *workaround_for_ill_designed_api = strdup( src );
 #endif
 
-    if( !WSAStringToAddress( workaround_for_ill_designed_api, af, NULL,
+    if( WSAStringToAddress( workaround_for_ill_designed_api, af, NULL,
                              (LPSOCKADDR)&addr, &len ) )
     {
         free( workaround_for_ill_designed_api );