[vlc-devel] [PATCH 1/3] [RFC] poll: keep the WSAEVENT per socket in memory while the socket is alive

Steve Lhomme robux4 at videolabs.io
Wed Jul 13 18:50:20 CEST 2016


In some cases we lose some events because the event is destroyed and recreated
only when we need to poll. It's better to keep the event receiver so we don't
miss events after the first WSAEnumNetworkEvents() call.
---
 compat/Makefile.am    |  1 +
 compat/poll.c         | 22 ++++++++++++++++++++--
 compat/poll.h         | 28 ++++++++++++++++++++++++++++
 include/vlc_network.h |  3 ++-
 src/libvlccore.sym    |  1 +
 src/missing.c         |  9 +++++++++
 src/win32/winsock.c   |  8 ++++++++
 7 files changed, 69 insertions(+), 3 deletions(-)
 create mode 100644 compat/poll.h

diff --git a/compat/Makefile.am b/compat/Makefile.am
index 58094d4..e1f0c1d 100644
--- a/compat/Makefile.am
+++ b/compat/Makefile.am
@@ -2,6 +2,7 @@ pkglib_LTLIBRARIES = libcompat.la
 libcompat_la_SOURCES = dummy.c
 libcompat_la_LIBADD = $(LTLIBOBJS) $(LIBRT)
 libcompat_la_LDFLAGS = -no-undefined -static
+noinst_HEADERS = poll.h
 
 BUILT_SOURCES = dummy.c
 CLEANFILES = dummy.c
diff --git a/compat/poll.c b/compat/poll.c
index fa94c93..91c2d81 100644
--- a/compat/poll.c
+++ b/compat/poll.c
@@ -108,6 +108,25 @@ int (poll) (struct pollfd *fds, unsigned nfds, int timeout)
 #else
 # include <windows.h>
 # include <winsock2.h>
+# include "poll.h"
+
+static WSAEVENT opened_events[4096] = {};
+
+WSAEVENT *win32_get_socket_event(int fd)
+{
+    if (opened_events[fd] == 0)
+        opened_events[fd] = WSACreateEvent();
+    return opened_events[fd];
+}
+
+void win32_close_socket_event(int fd)
+{
+    if (opened_events[fd] != 0)
+    {
+        WSACloseEvent(opened_events[fd]);
+        opened_events[fd] = 0;
+    }
+}
 
 int poll(struct pollfd *fds, unsigned nfds, int timeout)
 {
@@ -154,7 +173,7 @@ int poll(struct pollfd *fds, unsigned nfds, int timeout)
 
         fds[i].revents = 0;
 
-        evts[i] = WSACreateEvent();
+        evts[i] = win32_get_socket_event(fd);
         if (evts[i] == WSA_INVALID_EVENT)
         {
             while (i > 0)
@@ -201,7 +220,6 @@ int poll(struct pollfd *fds, unsigned nfds, int timeout)
         if (WSAEnumNetworkEvents(fds[i].fd, evts[i], &ne))
             memset(&ne, 0, sizeof (ne));
         WSAEventSelect(fds[i].fd, evts[i], 0);
-        WSACloseEvent(evts[i]);
 
         if (ne.lNetworkEvents & FD_CONNECT)
         {
diff --git a/compat/poll.h b/compat/poll.h
new file mode 100644
index 0000000..78ffc8c
--- /dev/null
+++ b/compat/poll.h
@@ -0,0 +1,28 @@
+/*****************************************************************************
+ * poll.c: poll() emulation
+ *****************************************************************************
+ * Copyright © 2016 VLC authors, VideoLAN and VideoLabs
+ *
+ * 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.
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#ifdef _WIN32
+extern WSAEVENT *win32_get_socket_event(int fd);
+extern void win32_close_socket_event(int fd);
+#endif
diff --git a/include/vlc_network.h b/include/vlc_network.h
index 8779ad2..1b627eb 100644
--- a/include/vlc_network.h
+++ b/include/vlc_network.h
@@ -133,7 +133,7 @@ VLC_API ssize_t net_vaPrintf( vlc_object_t *p_this, int fd, const char *psz_fmt,
 # define SHUT_RD SD_RECEIVE
 # define SHUT_WR SD_SEND
 # define SHUT_RDWR SD_BOTH
-# define net_Close( fd ) closesocket ((SOCKET)fd)
+# define net_Close( fd ) vlc_net_close (fd)
 #else
 # ifdef __OS2__
 #  define SHUT_RD    0
@@ -144,6 +144,7 @@ VLC_API ssize_t net_vaPrintf( vlc_object_t *p_this, int fd, const char *psz_fmt,
 VLC_API int vlc_close(int);
 # define net_Close( fd ) (void)vlc_close (fd)
 #endif
+VLC_API int vlc_net_close( int fd );
 
 /* Portable network names/addresses resolution layer */
 
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 89e74f8..a1211f1 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -290,6 +290,7 @@ net_Read
 net_SetCSCov
 net_vaPrintf
 net_Write
+vlc_net_close
 NTPtime64
 picture_BlendSubpicture
 picture_CopyPixels
diff --git a/src/missing.c b/src/missing.c
index 692b9b5..e533dc3 100644
--- a/src/missing.c
+++ b/src/missing.c
@@ -38,6 +38,15 @@
 #include <vlc_common.h>
 #include <assert.h>
 
+#ifndef _WIN32
+# include <vlc_network.h>
+int vlc_net_close( int fd )
+{
+    (void) fd;
+    vlc_assert_unreachable ();
+}
+#endif
+
 #ifndef ENABLE_HTTPD
 # include <vlc_httpd.h>
 
diff --git a/src/win32/winsock.c b/src/win32/winsock.c
index cac83fd..185303d 100644
--- a/src/win32/winsock.c
+++ b/src/win32/winsock.c
@@ -25,6 +25,14 @@
 #include <vlc_common.h>
 #include <vlc_network.h>
 
+#include "../../compat/poll.h"
+
+int vlc_net_close( int fd )
+{
+    win32_close_socket_event(fd);
+    return closesocket((SOCKET)fd);
+}
+
 #if 0
 ssize_t vlc_sendmsg (int s, struct msghdr *hdr, int flags)
 {
-- 
2.8.2



More information about the vlc-devel mailing list