/*****************************************************************************
- * poll.c: poll() emulation for Winsock
+ * poll.c: poll() emulation
*****************************************************************************
- * Copyright © 2007 Rémi Denis-Courmont
+ * Copyright © 2007-2012 Rémi Denis-Courmont
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
*****************************************************************************/
#ifdef HAVE_CONFIG_H
-# include "config.h"
+# include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <errno.h>
-#include <vlc_common.h>
-
-#ifdef FD_SETSIZE
+#ifdef WIN32
+# ifdef FD_SETSIZE
/* Too late for #undef FD_SETSIZE to work: fd_set is already defined. */
-# error Header inclusion order compromised!
+# error Header inclusion order compromised!
+# endif
+# define FD_SETSIZE 0
+# include <winsock2.h>
+#else
+# include <sys/select.h>
#endif
-#define FD_SETSIZE 0
-#include <vlc_network.h>
-int vlc_poll (struct pollfd *fds, unsigned nfds, int timeout)
+int (poll) (struct pollfd *fds, unsigned nfds, int timeout)
{
+#ifdef WIN32
size_t setsize = sizeof (fd_set) + nfds * sizeof (SOCKET);
fd_set *rdset = malloc (setsize);
fd_set *wrset = malloc (setsize);
fd_set *exset = malloc (setsize);
- struct timeval tv = { 0, 0 };
- int val;
- if (unlikely(rdset == NULL || wrset == NULL || exset == NULL))
+ if (rdset == NULL || wrset == NULL || exset == NULL)
{
free (rdset);
free (wrset);
errno = ENOMEM;
return -1;
}
-
/* Winsock FD_SET uses FD_SETSIZE in its expansion */
-#undef FD_SETSIZE
-#define FD_SETSIZE (nfds)
-
-resume:
- val = -1;
- vlc_testcancel ();
+# undef FD_SETSIZE
+# define FD_SETSIZE (nfds)
+#else
+ fd_set rdset[1], wrset[1], exset[1];
+#endif
+ struct timeval tv = { 0, 0 };
+ int val = -1;
FD_ZERO (rdset);
FD_ZERO (wrset);
* Note that Vista has a much nicer WSAPoll(), but Mingw does not
* support it yet.
*/
+#ifndef WIN32
+ if ((unsigned)fd >= FD_SETSIZE)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+#endif
if (fds[i].events & POLLIN)
- FD_SET ((SOCKET)fd, rdset);
+ FD_SET (fd, rdset);
if (fds[i].events & POLLOUT)
- FD_SET ((SOCKET)fd, wrset);
+ FD_SET (fd, wrset);
if (fds[i].events & POLLPRI)
- FD_SET ((SOCKET)fd, exset);
+ FD_SET (fd, exset);
}
-#ifndef HAVE_ALERTABLE_SELECT
-# warning FIXME! Fix cancellation and remove this crap.
- if ((timeout < 0) || (timeout > 50))
- {
- tv.tv_sec = 0;
- tv.tv_usec = 50000;
- }
- else
-#endif
if (timeout >= 0)
{
div_t d = div (timeout, 1000);
}
val = select (val + 1, rdset, wrset, exset,
- /*(timeout >= 0) ?*/ &tv /*: NULL*/);
-
-#ifndef HAVE_ALERTABLE_SELECT
- if (val == 0)
- {
- if (timeout > 0)
- timeout -= (timeout > 50) ? 50 : timeout;
- if (timeout != 0)
- goto resume;
- }
-#endif
-
+ (timeout >= 0) ? &tv : NULL);
if (val == -1)
return -1;
| (FD_ISSET (fd, wrset) ? POLLOUT : 0)
| (FD_ISSET (fd, exset) ? POLLPRI : 0);
}
+#ifdef WIN32
free (exset);
free (wrset);
free (rdset);
+#endif
return val;
}
dnl Check for usual libc functions
AC_CHECK_DECLS([nanosleep],,,[#include <time.h>])
AC_CHECK_FUNCS([daemon fcntl fstatvfs fork getenv getpwuid_r if_nameindex if_nametoindex isatty lstat memalign mmap openat pread posix_fadvise posix_madvise setlocale stricmp strnicmp strptime uselocale])
-AC_REPLACE_FUNCS([atof atoll dirfd fdopendir flockfile fsync getdelim getpid gmtime_r inet_pton lldiv localtime_r nrand48 rewind setenv strcasecmp strcasestr strdup strlcpy strncasecmp strndup strnlen strsep strtof strtok_r strtoll swab tdestroy])
+AC_REPLACE_FUNCS([atof atoll dirfd fdopendir flockfile fsync getdelim getpid gmtime_r inet_pton lldiv localtime_r nrand48 poll rewind setenv strcasecmp strcasestr strdup strlcpy strncasecmp strndup strnlen strsep strtof strtok_r strtoll swab tdestroy])
AC_CHECK_FUNCS(fdatasync,,
[AC_DEFINE(fdatasync, fsync, [Alias fdatasync() to fsync() if missing.])
])
AH_BOTTOM([#include <vlc_fixups.h>])
-dnl Check for poll
-AC_SEARCH_LIBS(poll, [poll], [
- AC_DEFINE(HAVE_POLL, 1, [Define to 1 if the OS has poll().])
-], [
- AS_IF([test "${SYS}" != "mingw32" -a "${SYS}" != "mingwce" -a "${SYS}" != "os2"], [
- AC_MSG_ERROR([poll() is required.])
- ])
-])
-
dnl Check for struct pollfd
AC_CHECK_TYPES([struct pollfd],,,
[#include <sys/types.h>
win32/atomic.c \
win32/filesystem.c \
win32/plugin.c \
- win32/poll.c \
win32/thread.c \
win32/specific.c \
win32/winsock.c \
misc/atomic.c \
posix/filesystem.c \
posix/plugin.c \
- os2/poll.c \
os2/thread.c \
os2/specific.c \
os2/rand.c \
+++ /dev/null
-/*****************************************************************************
- * poll.c: poll() emulation for OS/2
- *****************************************************************************
- * Copyright © 2011 KO Myung-Hun <komh@chollian.et>
- * Copyright © 2007 Rémi Denis-Courmont
- *
- * This program 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.
- *
- * This program 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/time.h>
-
-#include <vlc_common.h>
-#include <vlc_network.h>
-
-int vlc_poll (struct pollfd *fds, unsigned nfds, int timeout)
-{
- fd_set rdset;
- fd_set wrset;
- fd_set exset;
- struct timeval tv = { 0, 0 };
- int val;
-
-resume:
- val = -1;
- vlc_testcancel ();
-
- FD_ZERO (&rdset);
- FD_ZERO (&wrset);
- FD_ZERO (&exset);
- for (unsigned i = 0; i < nfds; i++)
- {
- int fd = fds[i].fd;
-
- if (fds[i].fd >= FD_SETSIZE)
- {
- errno = EINVAL;
- return -1;
- }
-
- if (val < fd)
- val = fd;
-
- if (fds[i].events & POLLIN)
- FD_SET (fd, &rdset);
- if (fds[i].events & POLLOUT)
- FD_SET (fd, &wrset);
- if (fds[i].events & POLLPRI)
- FD_SET (fd, &exset);
- }
-
-#ifndef HAVE_ALERTABLE_SELECT
-# warning FIXME! Fix cancellation and remove this crap.
- if ((timeout < 0) || (timeout > 50))
- {
- tv.tv_sec = 0;
- tv.tv_usec = 50000;
- }
- else
-#endif
- if (timeout >= 0)
- {
- div_t d = div (timeout, 1000);
- tv.tv_sec = d.quot;
- tv.tv_usec = d.rem * 1000;
- }
-
- val = select (val + 1, &rdset, &wrset, &exset, &tv);
-
-#ifndef HAVE_ALERTABLE_SELECT
- if (val == 0)
- {
- if (timeout > 0)
- timeout -= (timeout > 50) ? 50 : timeout;
- if (timeout != 0)
- goto resume;
- }
-#endif
-
- if (val == -1)
- return -1;
-
- for (unsigned i = 0; i < nfds; i++)
- {
- int fd = fds[i].fd;
- fds[i].revents = (FD_ISSET (fd, &rdset) ? POLLIN : 0)
- | (FD_ISSET (fd, &wrset) ? POLLOUT : 0)
- | (FD_ISSET (fd, &exset) ? POLLPRI : 0);
- }
- return val;
-}
va_end (ap);
}
+int vlc_poll (struct pollfd *fds, unsigned nfds, int timeout)
+{
+ vlc_testcancel ();
+
+ while (timeout > 50)
+ {
+ int val = poll (fds, nfds, timeout);
+ if (val != 0)
+ return val;
+ timeout -= 50;
+ vlc_testcancel ();
+ }
+
+ return poll (fds, nfds, timeout);
+}
+
#define Q2LL( q ) ( *( long long * )&( q ))
/*** Clock ***/
va_end (ap);
}
+int vlc_poll (struct pollfd *fds, unsigned nfds, int timeout)
+{
+ vlc_testcancel ();
+
+ while (timeout > 50)
+ {
+ int val = poll (fds, nfds, timeout);
+ if (val != 0)
+ return val;
+ timeout -= 50;
+ vlc_testcancel ();
+ }
+
+ return poll (fds, nfds, timeout);
+}
/*** Clock ***/
mtime_t mdate (void)