os: Add poll emulation for mingw [v2]
v2: rename as 'xserver_poll' to avoid potential library name collisions. Provide 'xserver_poll.h' which uses the system poll where available and falls back to this emulation otherwise. Autodetects when this is required, building the emulation only then Source: https://github.com/bmc/poll Signed-off-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
parent
2a79be9e4d
commit
711c36558f
|
@ -219,9 +219,10 @@ dnl Checks for library functions.
|
|||
AC_CHECK_FUNCS([backtrace ffs geteuid getuid issetugid getresuid \
|
||||
getdtablesize getifaddrs getpeereid getpeerucred getprogname getzoneid \
|
||||
mmap posix_fallocate seteuid shmctl64 strncasecmp vasprintf vsnprintf \
|
||||
walkcontext setitimer])
|
||||
walkcontext setitimer poll])
|
||||
AC_CONFIG_LIBOBJ_DIR([os])
|
||||
AC_REPLACE_FUNCS([reallocarray strcasecmp strcasestr strlcat strlcpy strndup])
|
||||
AM_CONDITIONAL(POLL, [test "x$ac_cv_func_poll" = "xyes"])
|
||||
|
||||
AC_CHECK_DECLS([program_invocation_short_name], [], [], [[#include <errno.h>]])
|
||||
|
||||
|
|
|
@ -527,4 +527,7 @@
|
|||
/* Use input thread */
|
||||
#undef INPUTTHREAD
|
||||
|
||||
/* Have poll() */
|
||||
#undef HAVE_POLL
|
||||
|
||||
#endif /* _DIX_CONFIG_H_ */
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright © 2016 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _XSERVER_POLL_H_
|
||||
#define _XSERVER_POLL_H_
|
||||
|
||||
#ifndef _DIX_CONFIG_H_
|
||||
#error must inclue dix-config.h to use xserver_poll.h
|
||||
#endif
|
||||
|
||||
#if HAVE_POLL
|
||||
#include <poll.h>
|
||||
#define xserver_poll(fds, nfds, timeout) poll(fds, nfds, timeout)
|
||||
#else
|
||||
|
||||
#define POLLIN 0x01
|
||||
#define POLLPRI 0x02
|
||||
#define POLLOUT 0x04
|
||||
#define POLLERR 0x08
|
||||
#define POLLHUP 0x10
|
||||
#define POLLNVAL 0x20
|
||||
|
||||
struct pollfd
|
||||
{
|
||||
int fd;
|
||||
short events;
|
||||
short revents;
|
||||
};
|
||||
|
||||
typedef unsigned long nfds_t;
|
||||
|
||||
int xserver_poll (struct pollfd *pArray, nfds_t n_fds, int timeout);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _XSERVER_POLL_H_ */
|
|
@ -7,6 +7,8 @@ XDMCP_SRCS = xdmcp.c
|
|||
XORG_SRCS = log.c
|
||||
BUSFAULT_SRCS = busfault.c
|
||||
|
||||
XSERVER_POLL_SRCS=xserver_poll.c
|
||||
|
||||
libos_la_SOURCES = \
|
||||
WaitFor.c \
|
||||
access.c \
|
||||
|
@ -32,6 +34,11 @@ if SECURE_RPC
|
|||
libos_la_SOURCES += $(SECURERPC_SRCS)
|
||||
endif
|
||||
|
||||
if POLL
|
||||
else
|
||||
libos_la_SOURCES += $(XSERVER_POLL_SRCS)
|
||||
endif
|
||||
|
||||
if XDMCP
|
||||
libos_la_SOURCES += $(XDMCP_SRCS)
|
||||
endif
|
||||
|
|
|
@ -0,0 +1,277 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
$Id$
|
||||
|
||||
NAME
|
||||
|
||||
poll - select(2)-based poll() emulation function for BSD systems.
|
||||
|
||||
SYNOPSIS
|
||||
#include "poll.h"
|
||||
|
||||
struct pollfd
|
||||
{
|
||||
int fd;
|
||||
short events;
|
||||
short revents;
|
||||
}
|
||||
|
||||
int poll (struct pollfd *pArray, unsigned long n_fds, int timeout)
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
This file, and the accompanying "poll.h", implement the System V
|
||||
poll(2) system call for BSD systems (which typically do not provide
|
||||
poll()). Poll() provides a method for multiplexing input and output
|
||||
on multiple open file descriptors; in traditional BSD systems, that
|
||||
capability is provided by select(). While the semantics of select()
|
||||
differ from those of poll(), poll() can be readily emulated in terms
|
||||
of select() -- which is how this function is implemented.
|
||||
|
||||
REFERENCES
|
||||
Stevens, W. Richard. Unix Network Programming. Prentice-Hall, 1990.
|
||||
|
||||
NOTES
|
||||
1. This software requires an ANSI C compiler.
|
||||
|
||||
LICENSE
|
||||
|
||||
This software is released under the following BSD license, adapted from
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
Copyright (c) 1995-2011, Brian M. Clapper
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the clapper.org nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Includes
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <unistd.h> /* standard Unix definitions */
|
||||
#include <sys/types.h> /* system types */
|
||||
#include <sys/time.h> /* time definitions */
|
||||
#include <assert.h> /* assertion macros */
|
||||
#include <string.h> /* string functions */
|
||||
#include "xserver_poll.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Macros
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Private Functions
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
static int map_poll_spec
|
||||
(struct pollfd *pArray,
|
||||
nfds_t n_fds,
|
||||
fd_set *pReadSet,
|
||||
fd_set *pWriteSet,
|
||||
fd_set *pExceptSet)
|
||||
{
|
||||
register nfds_t i; /* loop control */
|
||||
register struct pollfd *pCur; /* current array element */
|
||||
register int max_fd = -1; /* return value */
|
||||
|
||||
/*
|
||||
Map the poll() structures into the file descriptor sets required
|
||||
by select().
|
||||
*/
|
||||
for (i = 0, pCur = pArray; i < n_fds; i++, pCur++)
|
||||
{
|
||||
/* Skip any bad FDs in the array. */
|
||||
|
||||
if (pCur->fd < 0)
|
||||
continue;
|
||||
|
||||
if (pCur->events & POLLIN)
|
||||
{
|
||||
/* "Input Ready" notification desired. */
|
||||
FD_SET (pCur->fd, pReadSet);
|
||||
}
|
||||
|
||||
if (pCur->events & POLLOUT)
|
||||
{
|
||||
/* "Output Possible" notification desired. */
|
||||
FD_SET (pCur->fd, pWriteSet);
|
||||
}
|
||||
|
||||
if (pCur->events & POLLPRI)
|
||||
{
|
||||
/*
|
||||
"Exception Occurred" notification desired. (Exceptions
|
||||
include out of band data.
|
||||
*/
|
||||
FD_SET (pCur->fd, pExceptSet);
|
||||
}
|
||||
|
||||
max_fd = MAX (max_fd, pCur->fd);
|
||||
}
|
||||
|
||||
return max_fd;
|
||||
}
|
||||
|
||||
static struct timeval *map_timeout
|
||||
(int poll_timeout, struct timeval *pSelTimeout)
|
||||
{
|
||||
struct timeval *pResult;
|
||||
|
||||
/*
|
||||
Map the poll() timeout value into a select() timeout. The possible
|
||||
values of the poll() timeout value, and their meanings, are:
|
||||
|
||||
VALUE MEANING
|
||||
|
||||
-1 wait indefinitely (until signal occurs)
|
||||
0 return immediately, don't block
|
||||
>0 wait specified number of milliseconds
|
||||
|
||||
select() uses a "struct timeval", which specifies the timeout in
|
||||
seconds and microseconds, so the milliseconds value has to be mapped
|
||||
accordingly.
|
||||
*/
|
||||
|
||||
assert (pSelTimeout != (struct timeval *) NULL);
|
||||
|
||||
switch (poll_timeout)
|
||||
{
|
||||
case -1:
|
||||
/*
|
||||
A NULL timeout structure tells select() to wait indefinitely.
|
||||
*/
|
||||
pResult = (struct timeval *) NULL;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
/*
|
||||
"Return immediately" (test) is specified by all zeros in
|
||||
a timeval structure.
|
||||
*/
|
||||
pSelTimeout->tv_sec = 0;
|
||||
pSelTimeout->tv_usec = 0;
|
||||
pResult = pSelTimeout;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Wait the specified number of milliseconds. */
|
||||
pSelTimeout->tv_sec = poll_timeout / 1000; /* get seconds */
|
||||
poll_timeout %= 1000; /* remove seconds */
|
||||
pSelTimeout->tv_usec = poll_timeout * 1000; /* get microseconds */
|
||||
pResult = pSelTimeout;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return pResult;
|
||||
}
|
||||
|
||||
static void map_select_results
|
||||
(struct pollfd *pArray,
|
||||
unsigned long n_fds,
|
||||
fd_set *pReadSet,
|
||||
fd_set *pWriteSet,
|
||||
fd_set *pExceptSet)
|
||||
{
|
||||
register unsigned long i; /* loop control */
|
||||
register struct pollfd *pCur; /* current array element */
|
||||
|
||||
for (i = 0, pCur = pArray; i < n_fds; i++, pCur++)
|
||||
{
|
||||
/* Skip any bad FDs in the array. */
|
||||
|
||||
if (pCur->fd < 0)
|
||||
continue;
|
||||
|
||||
/* Exception events take priority over input events. */
|
||||
|
||||
pCur->revents = 0;
|
||||
if (FD_ISSET (pCur->fd, pExceptSet))
|
||||
pCur->revents |= POLLPRI;
|
||||
|
||||
else if (FD_ISSET (pCur->fd, pReadSet))
|
||||
pCur->revents |= POLLIN;
|
||||
|
||||
if (FD_ISSET (pCur->fd, pWriteSet))
|
||||
pCur->revents |= POLLOUT;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Public Functions
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
int xserver_poll
|
||||
(struct pollfd *pArray, unsigned long n_fds, int timeout)
|
||||
{
|
||||
fd_set read_descs; /* input file descs */
|
||||
fd_set write_descs; /* output file descs */
|
||||
fd_set except_descs; /* exception descs */
|
||||
struct timeval stime; /* select() timeout value */
|
||||
int ready_descriptors; /* function result */
|
||||
int max_fd; /* maximum fd value */
|
||||
struct timeval *pTimeout; /* actually passed */
|
||||
|
||||
FD_ZERO (&read_descs);
|
||||
FD_ZERO (&write_descs);
|
||||
FD_ZERO (&except_descs);
|
||||
|
||||
assert (pArray != (struct pollfd *) NULL);
|
||||
|
||||
/* Map the poll() file descriptor list in the select() data structures. */
|
||||
|
||||
max_fd = map_poll_spec (pArray, n_fds,
|
||||
&read_descs, &write_descs, &except_descs);
|
||||
|
||||
/* Map the poll() timeout value in the select() timeout structure. */
|
||||
|
||||
pTimeout = map_timeout (timeout, &stime);
|
||||
|
||||
/* Make the select() call. */
|
||||
|
||||
ready_descriptors = select (max_fd + 1, &read_descs, &write_descs,
|
||||
&except_descs, pTimeout);
|
||||
|
||||
if (ready_descriptors >= 0)
|
||||
{
|
||||
map_select_results (pArray, n_fds,
|
||||
&read_descs, &write_descs, &except_descs);
|
||||
}
|
||||
|
||||
return ready_descriptors;
|
||||
}
|
Loading…
Reference in New Issue