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

Rémi Denis-Courmont remi at remlab.net
Sat Jul 16 11:38:36 CEST 2016


Le keskiviikkona 13. heinäkuuta 2016, 18.50.20 EEST Steve Lhomme a écrit :
> 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] = {};

Does Windows actually warranty that socket handles are "small" numbers? It 
would work if we wrapped sockets behind _open_osfhandle(), but we do not (and 
it would bring some other complications).

> +
> +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;
> +    }
> +}

poll() is supposed to be reentrant. For instance, one thread can wait for 
reading while another thread waits for writing on the same socket.

I also suspect this does not handle duplicated socket handles correctly.

>  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)
>  {


-- 
Rémi Denis-Courmont
http://www.remlab.net/



More information about the vlc-devel mailing list