Commit ad3d32f6 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Experimental poll()-capable merge of net_Read, net_ReadNonBlock and net_Select

parent cc960e5b
...@@ -74,6 +74,7 @@ AC_CHECK_TOOL(LD, ld, :) ...@@ -74,6 +74,7 @@ AC_CHECK_TOOL(LD, ld, :)
dnl Check for compiler properties dnl Check for compiler properties
AC_C_CONST AC_C_CONST
AC_C_INLINE AC_C_INLINE
AC_C_RESTRICT
dnl dnl
dnl Check for the contrib directory dnl Check for the contrib directory
...@@ -784,6 +785,8 @@ fi # end "${SYS}" != "mingw32" -a "${SYS}" != "mingwce" ...@@ -784,6 +785,8 @@ fi # end "${SYS}" != "mingw32" -a "${SYS}" != "mingwce"
AC_HEADER_TIME AC_HEADER_TIME
AC_SEARCH_LIBS(poll, [poll], [AC_DEFINE(HAVE_POLL, 1, [Define to 1 if the OS is usabl... err, has poll().])])
dnl Check for dirent dnl Check for dirent
need_dirent=false need_dirent=false
AC_CHECK_HEADERS(dirent.h,,[need_dirent=:]) AC_CHECK_HEADERS(dirent.h,,[need_dirent=:])
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* io.c: network I/O functions * io.c: network I/O functions
***************************************************************************** *****************************************************************************
* Copyright (C) 2004-2005 the VideoLAN team * Copyright (C) 2004-2005 the VideoLAN team
* Copyright © 2005-2006 Rémi Denis-Courmont
* $Id$ * $Id$
* *
* Authors: Laurent Aimar <fenrir@videolan.org> * Authors: Laurent Aimar <fenrir@videolan.org>
...@@ -29,6 +30,7 @@ ...@@ -29,6 +30,7 @@
#include <vlc/vlc.h> #include <vlc/vlc.h>
#include <errno.h> #include <errno.h>
#include <assert.h>
#ifdef HAVE_FCNTL_H #ifdef HAVE_FCNTL_H
# include <fcntl.h> # include <fcntl.h>
...@@ -39,6 +41,9 @@ ...@@ -39,6 +41,9 @@
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
# include <unistd.h> # include <unistd.h>
#endif #endif
#ifdef HAVE_POLL
# include <sys/poll.h>
#endif
#include "network.h" #include "network.h"
...@@ -136,6 +141,142 @@ void net_Close( int fd ) ...@@ -136,6 +141,142 @@ void net_Close( int fd )
#endif #endif
} }
static int
net_ReadInner( vlc_object_t *restrict p_this, unsigned fdc, const int *fdv,
v_socket_t *const *restrict vsv,
uint8_t *restrict buf, size_t buflen,
int wait_ms, vlc_bool_t waitall )
{
int total = 0, n;
do
{
if (waitall && (buflen == 0))
return total; // output buffer full
int delay_ms;
if (wait_ms != -1)
{
delay_ms = (wait_ms > 500) ? 500 : wait_ms;
wait_ms -= delay_ms;
}
else
delay_ms = 500;
#ifdef HAVE_POLL
struct pollfd ufd[fdc];
memset (ufd, 0, sizeof (ufd));
for (unsigned i = 0; i < fdc; i++)
{
ufd[i].fd = fdv[i];
ufd[i].events = POLLIN;
}
if (p_this->b_die)
return total;
n = poll (ufd, fdc, (wait_ms == -1) ? -1 : delay_ms);
if (n == -1)
goto error;
assert ((unsigned)n <= fdc);
for (int i = 0; n > 0; i++)
if (ufd[i].revents)
{
fdc = 1;
fdv += i;
vsv += i;
n--;
goto receive;
}
#else
int maxfd = -1;
fd_set set;
FD_ZERO (&set);
for (unsigned i = 0; i < fdc; i++)
{
#if !defined(WIN32) && !defined(UNDER_CE)
if (fdv[i] >= FD_SETSIZE)
{
/* We don't want to overflow select() fd_set */
msg_Err( p_this, "select set overflow" );
return -1;
}
#endif
FD_SET (fdv[i], &set);
if (fdv[i] > maxfd)
maxfd = fdv[i];
}
n = select (maxfd + 1, &set, NULL, NULL,
(wait_ms == -1) ? NULL
: &(struct timeval){ 0, delay_ms * 1000 });
if (n == -1)
goto error;
for (unsigned i = 0; n > 0; i++)
if (FD_ISSET (fdv[i], &set))
{
fdc = 1;
fdv += i;
vsv += i;
n--;
goto receive;
}
#endif
continue;
receive:
if ((*vsv) != NULL)
n = (*vsv)->pf_recv ((*vsv)->p_sys, buf, buflen);
else
n = recv (*fdv, buf, buflen, 0);
if (n == -1)
{
#if defined(WIN32) || defined(UNDER_CE)
switch (WSAGetLastError())
{
case WSAEWOULDBLOCK:
/* only happens with vs != NULL (SSL) - not really an error */
continue;
case WSAEMSGSIZE:
/* For UDP only */
/* On Win32, recv() fails if the datagram doesn't fit inside
* the passed buffer, even though the buffer will be filled
* with the first part of the datagram. */
msg_Err( p_this, "recv() failed. "
"Increase the mtu size (--mtu option)" );
total += buflen;
return total;
}
#else
if( errno == EAGAIN ) /* spurious wake-up (sucks if fdc > 1) */
continue;
#endif
goto error;
}
total += n;
buf += n;
buflen -= n;
}
while (wait_ms);
return total; // timeout
error:
msg_Err (p_this, "Receive error: %s", net_strerror (net_errno));
return (total > 0) ? total : -1;
}
/***************************************************************************** /*****************************************************************************
* __net_Read: * __net_Read:
***************************************************************************** *****************************************************************************
...@@ -143,8 +284,9 @@ void net_Close( int fd ) ...@@ -143,8 +284,9 @@ void net_Close( int fd )
* If b_retry is true, then we repeat until we have read the right amount of * If b_retry is true, then we repeat until we have read the right amount of
* data * data
*****************************************************************************/ *****************************************************************************/
int __net_Read( vlc_object_t *p_this, int fd, v_socket_t *p_vs, int __net_Read( vlc_object_t *restrict p_this, int fd,
uint8_t *p_data, int i_data, vlc_bool_t b_retry ) v_socket_t *restrict p_vs,
uint8_t *restrict p_data, int i_data, vlc_bool_t b_retry )
{ {
struct timeval timeout; struct timeval timeout;
fd_set fds_r, fds_e; fd_set fds_r, fds_e;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment