[vlc-devel] [PATCH 2/4] vlccore: implementation of cancel-able poll() for OS/2

KO Myung-Hun komh78 at gmail.com
Wed Jan 30 08:34:51 CET 2013


---
 compat/poll.c   |   18 +---------
 src/Makefile.am |    1 +
 src/os2/poll.c  |  104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 106 insertions(+), 17 deletions(-)
 create mode 100644 src/os2/poll.c

diff --git a/compat/poll.c b/compat/poll.c
index ef00fa5..7558a22 100644
--- a/compat/poll.c
+++ b/compat/poll.c
@@ -33,14 +33,9 @@
 # endif
 # define FD_SETSIZE 0
 # include <winsock2.h>
-#else
-# include <sys/time.h>
-# include <sys/select.h>
-#endif
 
 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);
@@ -57,9 +52,6 @@ int (poll) (struct pollfd *fds, unsigned nfds, int timeout)
 /* Winsock FD_SET uses FD_SETSIZE in its expansion */
 # 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;
 
@@ -89,13 +81,6 @@ int (poll) (struct pollfd *fds, unsigned nfds, int timeout)
          * 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 (fd, rdset);
         if (fds[i].events & POLLOUT)
@@ -123,10 +108,9 @@ int (poll) (struct pollfd *fds, unsigned nfds, int timeout)
                        | (FD_ISSET (fd, wrset) ? POLLOUT : 0)
                        | (FD_ISSET (fd, exset) ? POLLPRI : 0);
     }
-#ifdef WIN32
     free (exset);
     free (wrset);
     free (rdset);
-#endif
     return val;
 }
+#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index f87581d..33ecf1f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -309,6 +309,7 @@ SOURCES_libvlc_os2 = \
 	os2/thread.c \
 	os2/specific.c \
 	os2/rand.c \
+	os2/poll.c \
 	$(NULL)
 
 SOURCES_libvlc_other = \
diff --git a/src/os2/poll.c b/src/os2/poll.c
new file mode 100644
index 0000000..5c74f48
--- /dev/null
+++ b/src/os2/poll.c
@@ -0,0 +1,104 @@
+/*****************************************************************************
+ * poll.c: poll() emulation for OS/2
+ *****************************************************************************
+ * Copyright © 2007-2012 Rémi Denis-Courmont
+ * Copyright (c) 2013 KO Myung-Hun
+ *
+ * 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 <sys/select.h>
+
+#include <vlc_common.h>
+
+int (poll) (struct pollfd *fds, unsigned nfds, int timeout)
+{
+    fd_set rdset, wrset, exset;
+
+    struct timeval tv = { 0, 0 };
+    int val = -1;
+
+    FD_ZERO (&rdset);
+    FD_ZERO (&wrset);
+    FD_ZERO (&exset);
+    for (unsigned i = 0; i < nfds; i++)
+    {
+        int fd = fds[i].fd;
+        if (val < fd)
+            val = fd;
+
+        if ((unsigned)fd >= FD_SETSIZE)
+        {
+            errno = EINVAL;
+            return -1;
+        }
+
+        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);
+    }
+
+    fd_set saved_rdset, saved_wrset, saved_exset;
+    int    saved_val;
+
+    saved_rdset = rdset;
+    saved_wrset = wrset;
+    saved_exset = exset;
+    saved_val   = val;
+
+    long wait_time = ( timeout == 0 ) ? 0 : (10 * 1000);
+
+    mtime_t deadline = mdate () + timeout * 1000;
+
+    do
+    {
+        vlc_testcancel ();
+
+        rdset = saved_rdset;
+        wrset = saved_wrset;
+        exset = saved_exset;
+        val   = saved_val;
+
+        tv.tv_sec  = 0;
+        tv.tv_usec = wait_time;
+
+        val = select (val + 1, &rdset, &wrset, &exset, &tv );
+    } while (val == 0 && (timeout < 0 || mdate () < deadline));
+
+    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;
+}
-- 
1.7.3.2




More information about the vlc-devel mailing list