Message ID | 1340712758-65898-7-git-send-email-martin@martin.st |
---|---|
State | Deferred |
Headers | show |
Martin Storsjö <martin@martin.st> writes: > This gives the advantage of using this function (instead of the > emulation via select) on systems where it is available, while > retaining compatibility with systems that do not have it. > > This requires making our fallback pollfd struct and constants > match what windows would use, so that a build that doesn't have > the windows pollfd definition available at build time would work > if the WSAPoll function is loaded at runtime. > --- > libavformat/network.c | 13 +++++++++++++ > libavformat/network.h | 3 +++ > libavformat/os_support.c | 3 +++ > libavformat/os_support.h | 24 ++++++++++++++---------- > 4 files changed, 33 insertions(+), 10 deletions(-) Is this really worth the complexity? I doubt we use poll() in a performance-sensitive way anywhere.
On Tue, 26 Jun 2012, Måns Rullgård wrote: > Martin Storsjö <martin@martin.st> writes: > >> This gives the advantage of using this function (instead of the >> emulation via select) on systems where it is available, while >> retaining compatibility with systems that do not have it. >> >> This requires making our fallback pollfd struct and constants >> match what windows would use, so that a build that doesn't have >> the windows pollfd definition available at build time would work >> if the WSAPoll function is loaded at runtime. >> --- >> libavformat/network.c | 13 +++++++++++++ >> libavformat/network.h | 3 +++ >> libavformat/os_support.c | 3 +++ >> libavformat/os_support.h | 24 ++++++++++++++---------- >> 4 files changed, 33 insertions(+), 10 deletions(-) > > Is this really worth the complexity? I doubt we use poll() in a > performance-sensitive way anywhere. I'm not sure. We do however call poll() once before each read() for TCP for instance. // Martin
Martin Storsjö <martin@martin.st> writes: > On Tue, 26 Jun 2012, Måns Rullgård wrote: > >> Martin Storsjö <martin@martin.st> writes: >> >>> This gives the advantage of using this function (instead of the >>> emulation via select) on systems where it is available, while >>> retaining compatibility with systems that do not have it. >>> >>> This requires making our fallback pollfd struct and constants >>> match what windows would use, so that a build that doesn't have >>> the windows pollfd definition available at build time would work >>> if the WSAPoll function is loaded at runtime. >>> --- >>> libavformat/network.c | 13 +++++++++++++ >>> libavformat/network.h | 3 +++ >>> libavformat/os_support.c | 3 +++ >>> libavformat/os_support.h | 24 ++++++++++++++---------- >>> 4 files changed, 33 insertions(+), 10 deletions(-) >> >> Is this really worth the complexity? I doubt we use poll() in a >> performance-sensitive way anywhere. > > I'm not sure. We do however call poll() once before each read() for > TCP for instance. Yes, but only on one file descriptor. select() can still perform badly if this file descriptor has a very large value, but is that really very likely, especially on a system that doesn't have poll()?
On Tue, 26 Jun 2012, Måns Rullgård wrote: > Martin Storsjö <martin@martin.st> writes: > >> On Tue, 26 Jun 2012, Måns Rullgård wrote: >> >>> Martin Storsjö <martin@martin.st> writes: >>> >>>> This gives the advantage of using this function (instead of the >>>> emulation via select) on systems where it is available, while >>>> retaining compatibility with systems that do not have it. >>>> >>>> This requires making our fallback pollfd struct and constants >>>> match what windows would use, so that a build that doesn't have >>>> the windows pollfd definition available at build time would work >>>> if the WSAPoll function is loaded at runtime. >>>> --- >>>> libavformat/network.c | 13 +++++++++++++ >>>> libavformat/network.h | 3 +++ >>>> libavformat/os_support.c | 3 +++ >>>> libavformat/os_support.h | 24 ++++++++++++++---------- >>>> 4 files changed, 33 insertions(+), 10 deletions(-) >>> >>> Is this really worth the complexity? I doubt we use poll() in a >>> performance-sensitive way anywhere. >> >> I'm not sure. We do however call poll() once before each read() for >> TCP for instance. > > Yes, but only on one file descriptor. select() can still perform badly > if this file descriptor has a very large value, but is that really very > likely, especially on a system that doesn't have poll()? No idea. IIRC the windows select fdset implementation isn't bitfield based, so there might not be that much an issue with it at all. Anyway, this (and the following ones) dropped for now. // Martin
diff --git a/libavformat/network.c b/libavformat/network.c index c2f7a9b..c702214 100644 --- a/libavformat/network.c +++ b/libavformat/network.c @@ -121,6 +121,12 @@ void ff_tls_deinit(void) int ff_network_inited_globally; +#if HAVE_WINSOCK2_H +static int ff_winsock_ptrs_loaded; +int (WSAAPI *ff_wsapoll_ptr)(struct pollfd *fds, unsigned long nfds, + int timeout); +#endif + int ff_network_init(void) { #if HAVE_WINSOCK2_H @@ -135,6 +141,13 @@ int ff_network_init(void) #if HAVE_WINSOCK2_H if (WSAStartup(MAKEWORD(1,1), &wsaData)) return 0; + if (!ff_winsock_ptrs_loaded && ff_network_inited_globally) { + /* Only do this init if we're called from avformat_network_init, + * which should be done before spawning any threads. */ + HMODULE ws2mod = GetModuleHandle("ws2_32.dll"); + ff_wsapoll_ptr = GetProcAddress(ws2mod, "WSAPoll"); + ff_winsock_ptrs_loaded = 1; + } #endif return 1; } diff --git a/libavformat/network.h b/libavformat/network.h index 3724aa2..8fb7a82 100644 --- a/libavformat/network.h +++ b/libavformat/network.h @@ -51,6 +51,9 @@ #define setsockopt(a, b, c, d, e) setsockopt(a, b, c, (const char*) d, e) int ff_neterrno(void); + +extern int (WSAAPI *ff_wsapoll_ptr)(struct pollfd *fds, unsigned long nfds, + int timeout); #else #include <sys/types.h> #include <sys/socket.h> diff --git a/libavformat/os_support.c b/libavformat/os_support.c index 04e5f9c..9ef63eb 100644 --- a/libavformat/os_support.c +++ b/libavformat/os_support.c @@ -284,6 +284,9 @@ int ff_poll(struct pollfd *fds, nfds_t numfds, int timeout) int rc; #if HAVE_WINSOCK2_H + if (ff_wsapoll_ptr) + return ff_wsapoll_ptr(fds, numfds, timeout); + if (numfds >= FD_SETSIZE) { errno = EINVAL; return -1; diff --git a/libavformat/os_support.h b/libavformat/os_support.h index 04f22d2..1afdd38 100644 --- a/libavformat/os_support.h +++ b/libavformat/os_support.h @@ -83,24 +83,28 @@ typedef unsigned long nfds_t; #endif #if !HAVE_STRUCT_POLLFD struct pollfd { +#if HAVE_WINSOCK2_H + SOCKET fd; +#else int fd; +#endif short events; /* events to look for */ short revents; /* events that occurred */ }; /* events & revents */ -#define POLLIN 0x0001 /* any readable data available */ -#define POLLOUT 0x0002 /* file descriptor is writeable */ -#define POLLRDNORM POLLIN -#define POLLWRNORM POLLOUT -#define POLLRDBAND 0x0008 /* priority readable data */ -#define POLLWRBAND 0x0010 /* priority data can be written */ -#define POLLPRI 0x0020 /* high priority readable data */ +#define POLLIN (POLLRDNORM | POLLRDBAND) /* any readable data available */ +#define POLLOUT (POLLWRNORM) /* file descriptor is writeable */ +#define POLLRDNORM 0x0100 +#define POLLWRNORM 0x0010 +#define POLLRDBAND 0x0200 /* priority readable data */ +#define POLLWRBAND 0x0020 /* priority data can be written */ +#define POLLPRI 0x0400 /* high priority readable data */ /* revents only */ -#define POLLERR 0x0004 /* errors pending */ -#define POLLHUP 0x0080 /* disconnected */ -#define POLLNVAL 0x1000 /* invalid file descriptor */ +#define POLLERR 0x0001 /* errors pending */ +#define POLLHUP 0x0002 /* disconnected */ +#define POLLNVAL 0x0004 /* invalid file descriptor */ #endif