Use poll() instead of select() when available
select() has the major drawback that it cannot handle file descriptor that are bigger than 1024. This patch makes use of poll() instead of select() when poll() support is available.
This commit is contained in:
parent
b86c3b038b
commit
542811291c
@ -369,6 +369,7 @@ if(UNIX OR CYGWIN)
|
||||
check_include_files(sys/eventfd.h HAVE_AIO_H)
|
||||
check_include_files(sys/eventfd.h HAVE_EVENTFD_H)
|
||||
check_include_files(sys/timerfd.h HAVE_TIMERFD_H)
|
||||
check_include_files(poll.h HAVE_POLL_H)
|
||||
set(X11_FEATURE_TYPE "RECOMMENDED")
|
||||
else()
|
||||
set(X11_FEATURE_TYPE "DISABLED")
|
||||
|
@ -24,6 +24,7 @@
|
||||
#cmakedefine HAVE_TIMERFD_H
|
||||
#cmakedefine HAVE_TM_GMTOFF
|
||||
#cmakedefine HAVE_AIO_H
|
||||
#cmakedefine HAVE_POLL_H
|
||||
#cmakedefine HAVE_PTHREAD_GNU_EXT
|
||||
#cmakedefine HAVE_VALGRIND_MEMCHECK_H
|
||||
|
||||
|
@ -41,6 +41,13 @@
|
||||
#include <netinet/tcp.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
#include <poll.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#ifndef SOL_TCP
|
||||
#define SOL_TCP IPPROTO_TCP
|
||||
@ -739,6 +746,83 @@ HANDLE tcp_get_event_handle(rdpTcp* tcp)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int tcp_wait_read(rdpTcp* tcp, DWORD dwMilliSeconds)
|
||||
{
|
||||
int status;
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
struct pollfd pollset;
|
||||
|
||||
pollset.fd = tcp->sockfd;
|
||||
pollset.events = POLLIN;
|
||||
pollset.revents = 0;
|
||||
|
||||
do
|
||||
{
|
||||
status = poll(&pollset, 1, dwMilliSeconds);
|
||||
}
|
||||
while ((status < 0) && (errno == EINTR));
|
||||
#else
|
||||
struct timeval tv;
|
||||
fd_set rset;
|
||||
|
||||
FD_ZERO(&rset);
|
||||
FD_SET(tcp->sockfd, &rset);
|
||||
|
||||
if (dwMilliSeconds)
|
||||
{
|
||||
tv.tv_sec = dwMilliSeconds / 1000;
|
||||
tv.tv_usec = (dwMilliSeconds % 1000) * 1000;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
status = select(tcp->sockfd + 1, &rset, NULL, NULL, dwMilliSeconds ? &tv : NULL);
|
||||
}
|
||||
while ((status < 0) && (errno == EINTR));
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
int tcp_wait_write(rdpTcp* tcp, DWORD dwMilliSeconds)
|
||||
{
|
||||
int status;
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
struct pollfd pollset;
|
||||
|
||||
pollset.fd = tcp->sockfd;
|
||||
pollset.events = POLLOUT;
|
||||
pollset.revents = 0;
|
||||
|
||||
do
|
||||
{
|
||||
status = poll(&pollset, 1, dwMilliSeconds);
|
||||
}
|
||||
while ((status < 0) && (errno == EINTR));
|
||||
#else
|
||||
struct timeval tv;
|
||||
fd_set rset;
|
||||
|
||||
FD_ZERO(&rset);
|
||||
FD_SET(tcp->sockfd, &rset);
|
||||
|
||||
if (dwMilliSeconds)
|
||||
{
|
||||
tv.tv_sec = dwMilliSeconds / 1000;
|
||||
tv.tv_usec = (dwMilliSeconds % 1000) * 1000;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
status = select(tcp->sockfd + 1, NULL, &rset, NULL, dwMilliSeconds ? &tv : NULL);
|
||||
}
|
||||
while ((status < 0) && (errno == EINTR));
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
rdpTcp* tcp_new(rdpSettings* settings)
|
||||
{
|
||||
rdpTcp* tcp;
|
||||
|
@ -64,8 +64,8 @@ BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeout);
|
||||
BOOL tcp_disconnect(rdpTcp* tcp);
|
||||
int tcp_read(rdpTcp* tcp, BYTE* data, int length);
|
||||
int tcp_write(rdpTcp* tcp, BYTE* data, int length);
|
||||
int tcp_wait_read(rdpTcp* tcp);
|
||||
int tcp_wait_write(rdpTcp* tcp);
|
||||
int tcp_wait_read(rdpTcp* tcp, DWORD dwMilliSeconds);
|
||||
int tcp_wait_write(rdpTcp* tcp, DWORD dwMilliSeconds);
|
||||
BOOL tcp_set_blocking_mode(rdpTcp* tcp, BOOL blocking);
|
||||
BOOL tcp_set_keep_alive_mode(rdpTcp* tcp);
|
||||
int tcp_attach(rdpTcp* tcp, int sockfd);
|
||||
|
@ -43,9 +43,7 @@
|
||||
#ifndef _WIN32
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#ifdef HAVE_VALGRIND_MEMCHECK_H
|
||||
#include <valgrind/memcheck.h>
|
||||
@ -642,69 +640,37 @@ UINT32 nla_header_length(wStream* s)
|
||||
|
||||
static int transport_wait_for_read(rdpTransport* transport)
|
||||
{
|
||||
struct timeval tv;
|
||||
fd_set rset, wset;
|
||||
fd_set *rsetPtr = NULL, *wsetPtr = NULL;
|
||||
rdpTcp *tcpIn;
|
||||
|
||||
tcpIn = transport->TcpIn;
|
||||
rdpTcp *tcpIn = transport->TcpIn;
|
||||
|
||||
if (tcpIn->readBlocked)
|
||||
{
|
||||
rsetPtr = &rset;
|
||||
FD_ZERO(rsetPtr);
|
||||
FD_SET(tcpIn->sockfd, rsetPtr);
|
||||
return tcp_wait_read(tcpIn, 1000);
|
||||
}
|
||||
else if (tcpIn->writeBlocked)
|
||||
{
|
||||
wsetPtr = &wset;
|
||||
FD_ZERO(wsetPtr);
|
||||
FD_SET(tcpIn->sockfd, wsetPtr);
|
||||
return tcp_wait_write(tcpIn, 1000);
|
||||
}
|
||||
|
||||
if (!wsetPtr && !rsetPtr)
|
||||
{
|
||||
USleep(1000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 1000;
|
||||
|
||||
return select(tcpIn->sockfd + 1, rsetPtr, wsetPtr, NULL, &tv);
|
||||
USleep(1000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int transport_wait_for_write(rdpTransport* transport)
|
||||
{
|
||||
struct timeval tv;
|
||||
fd_set rset, wset;
|
||||
fd_set *rsetPtr = NULL, *wsetPtr = NULL;
|
||||
rdpTcp *tcpOut;
|
||||
|
||||
tcpOut = transport->SplitInputOutput ? transport->TcpOut : transport->TcpIn;
|
||||
if (tcpOut->writeBlocked)
|
||||
{
|
||||
wsetPtr = &wset;
|
||||
FD_ZERO(wsetPtr);
|
||||
FD_SET(tcpOut->sockfd, wsetPtr);
|
||||
return tcp_wait_write(tcpOut, 1000);
|
||||
}
|
||||
else if (tcpOut->readBlocked)
|
||||
{
|
||||
rsetPtr = &rset;
|
||||
FD_ZERO(rsetPtr);
|
||||
FD_SET(tcpOut->sockfd, rsetPtr);
|
||||
return tcp_wait_read(tcpOut, 1000);
|
||||
}
|
||||
|
||||
if (!wsetPtr && !rsetPtr)
|
||||
{
|
||||
USleep(1000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 1000;
|
||||
|
||||
return select(tcpOut->sockfd + 1, rsetPtr, wsetPtr, NULL, &tv);
|
||||
USleep(1000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int transport_read_layer(rdpTransport* transport, BYTE* data, int bytes)
|
||||
|
@ -33,6 +33,11 @@
|
||||
#include <freerdp/crypto/tls.h>
|
||||
#include "../core/tcp.h"
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
|
||||
struct _BIO_RDP_TLS
|
||||
{
|
||||
SSL* ssl;
|
||||
@ -586,8 +591,12 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode)
|
||||
|
||||
do
|
||||
{
|
||||
#ifdef HAVE_POLL_H
|
||||
struct pollfd pollfds;
|
||||
#else
|
||||
struct timeval tv;
|
||||
fd_set rset;
|
||||
#endif
|
||||
int fd;
|
||||
|
||||
status = BIO_do_handshake(tls->bio);
|
||||
@ -600,8 +609,6 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode)
|
||||
|
||||
/* we select() only for read even if we should test both read and write
|
||||
* depending of what have blocked */
|
||||
FD_ZERO(&rset);
|
||||
|
||||
fd = BIO_get_fd(tls->bio, NULL);
|
||||
|
||||
if (fd < 0)
|
||||
@ -610,12 +617,24 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
pollfds.fd = fd;
|
||||
pollfds.events = POLLIN;
|
||||
pollfds.revents = 0;
|
||||
|
||||
do
|
||||
{
|
||||
status = poll(&pollfds, 1, 10 * 1000);
|
||||
}
|
||||
while ((status < 0) && (errno == EINTR));
|
||||
#else
|
||||
FD_ZERO(&rset);
|
||||
FD_SET(fd, &rset);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 10 * 1000; /* 10ms */
|
||||
|
||||
status = select(fd + 1, &rset, NULL, NULL, &tv);
|
||||
|
||||
status = _select(fd + 1, &rset, NULL, NULL, &tv);
|
||||
#endif
|
||||
if (status < 0)
|
||||
{
|
||||
fprintf(stderr, "%s: error during select()\n", __FUNCTION__);
|
||||
@ -830,9 +849,13 @@ int tls_write_all(rdpTls* tls, const BYTE* data, int length)
|
||||
{
|
||||
int status, nchunks, commitedBytes;
|
||||
rdpTcp *tcp;
|
||||
#ifdef HAVE_POLL_H
|
||||
struct pollfd pollfds;
|
||||
#else
|
||||
fd_set rset, wset;
|
||||
fd_set *rsetPtr, *wsetPtr;
|
||||
struct timeval tv;
|
||||
#endif
|
||||
BIO* bio = tls->bio;
|
||||
DataChunk chunks[2];
|
||||
|
||||
@ -855,9 +878,34 @@ int tls_write_all(rdpTls* tls, const BYTE* data, int length)
|
||||
|
||||
if (!BIO_should_retry(bio))
|
||||
return -1;
|
||||
#ifdef HAVE_POLL_H
|
||||
pollfds.fd = tcp->sockfd;
|
||||
pollfds.revents = 0;
|
||||
pollfds.events = 0;
|
||||
|
||||
if (tcp->writeBlocked)
|
||||
{
|
||||
pollfds.events |= POLLOUT;
|
||||
}
|
||||
else if (tcp->readBlocked)
|
||||
{
|
||||
pollfds.events |= POLLIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "%s: weird we're blocked but the underlying is not read or write blocked !\n", __FUNCTION__);
|
||||
USleep(10);
|
||||
continue;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
status = poll(&pollfds, 1, 100);
|
||||
}
|
||||
while ((status < 0) && (errno == EINTR));
|
||||
#else
|
||||
/* we try to handle SSL want_read and want_write nicely */
|
||||
rsetPtr = wsetPtr = 0;
|
||||
rsetPtr = wsetPtr = NULL;
|
||||
|
||||
if (tcp->writeBlocked)
|
||||
{
|
||||
@ -881,8 +929,8 @@ int tls_write_all(rdpTls* tls, const BYTE* data, int length)
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 100 * 1000;
|
||||
|
||||
status = select(tcp->sockfd + 1, rsetPtr, wsetPtr, NULL, &tv);
|
||||
|
||||
status = _select(tcp->sockfd + 1, rsetPtr, wsetPtr, NULL, &tv);
|
||||
#endif
|
||||
if (status < 0)
|
||||
return -1;
|
||||
}
|
||||
@ -911,13 +959,24 @@ int tls_write_all(rdpTls* tls, const BYTE* data, int length)
|
||||
if (!BIO_should_retry(tcp->socketBio))
|
||||
goto out_fail;
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
pollfds.fd = tcp->sockfd;
|
||||
pollfds.events = POLLIN;
|
||||
pollfds.revents = 0;
|
||||
|
||||
do
|
||||
{
|
||||
status = poll(&pollfds, 1, 100);
|
||||
}
|
||||
while ((status < 0) && (errno == EINTR));
|
||||
#else
|
||||
FD_ZERO(&rset);
|
||||
FD_SET(tcp->sockfd, &rset);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 100 * 1000;
|
||||
|
||||
status = select(tcp->sockfd + 1, &rset, NULL, NULL, &tv);
|
||||
|
||||
status = _select(tcp->sockfd + 1, &rset, NULL, NULL, &tv);
|
||||
#endif
|
||||
if (status < 0)
|
||||
goto out_fail;
|
||||
}
|
||||
|
@ -41,11 +41,16 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/select.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
#include <poll.h>
|
||||
#else
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#ifndef TCP_KEEPIDLE
|
||||
#define TCP_KEEPIDLE TCP_KEEPALIVE
|
||||
@ -186,8 +191,14 @@ int freerdp_tcp_write(int sockfd, BYTE* data, int length)
|
||||
|
||||
int freerdp_tcp_wait_read(int sockfd)
|
||||
{
|
||||
int status;
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
struct pollfd pollfds;
|
||||
#else
|
||||
fd_set fds;
|
||||
struct timeval timeout;
|
||||
#endif
|
||||
|
||||
if (sockfd < 1)
|
||||
{
|
||||
@ -195,37 +206,61 @@ int freerdp_tcp_wait_read(int sockfd)
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
pollfds.fd = sockfd;
|
||||
pollfds.events = POLLIN;
|
||||
pollfds.revents = 0;
|
||||
do
|
||||
{
|
||||
status = poll(&pollfds, 1, 5 * 1000);
|
||||
}
|
||||
while ((status < 0) && (errno == EINTR));
|
||||
#else
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(sockfd, &fds);
|
||||
timeout.tv_sec = 5;
|
||||
timeout.tv_usec = 0;
|
||||
select(sockfd+1, &fds, NULL, NULL, &timeout);
|
||||
if (!FD_ISSET(sockfd, &fds))
|
||||
return -1;
|
||||
status = _select(sockfd+1, &fds, NULL, NULL, &timeout);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
return status > 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
int freerdp_tcp_wait_write(int sockfd)
|
||||
{
|
||||
int status;
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
struct pollfd pollfds;
|
||||
#else
|
||||
fd_set fds;
|
||||
struct timeval timeout;
|
||||
#endif
|
||||
|
||||
if (sockfd < 1)
|
||||
{
|
||||
fprintf(stderr, "Invalid socket to watch: %d\n", sockfd);
|
||||
return 0;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
pollfds.fd = sockfd;
|
||||
pollfds.events = POLLOUT;
|
||||
pollfds.revents = 0;
|
||||
do
|
||||
{
|
||||
status = poll(&pollfds, 1, 5 * 1000);
|
||||
}
|
||||
while ((status < 0) && (errno == EINTR));
|
||||
#else
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(sockfd, &fds);
|
||||
timeout.tv_sec = 5;
|
||||
timeout.tv_usec = 0;
|
||||
select(sockfd+1, NULL, &fds, NULL, &timeout);
|
||||
if (!FD_ISSET(sockfd, &fds))
|
||||
return -1;
|
||||
status = _select(sockfd+1, NULL, &fds, NULL, &timeout);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
return status > 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
int freerdp_tcp_disconnect(int sockfd)
|
||||
|
@ -3,6 +3,7 @@
|
||||
* Synchronization Functions
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2014 Hardening <contact@hardening-consulting.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -25,6 +26,10 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
@ -164,6 +169,47 @@ static void ts_add_ms(struct timespec *ts, DWORD dwMilliseconds)
|
||||
ts->tv_nsec = ts->tv_nsec % 1000000000L;
|
||||
}
|
||||
|
||||
static int waitOnFd(int fd, DWORD dwMilliseconds)
|
||||
{
|
||||
int status;
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
struct pollfd pollfds;
|
||||
|
||||
pollfds.fd = fd;
|
||||
pollfds.events = POLLIN;
|
||||
pollfds.revents = 0;
|
||||
|
||||
do
|
||||
{
|
||||
status = poll(&pollfds, 1, dwMilliseconds);
|
||||
}
|
||||
while ((status < 0) && (errno == EINTR));
|
||||
|
||||
#else
|
||||
struct timespec timeout;
|
||||
fd_set rfds;
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(fd, &rfds);
|
||||
ZeroMemory(&timeout, sizeof(timeout));
|
||||
|
||||
if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0))
|
||||
{
|
||||
timeout.tv_sec = dwMilliseconds / 1000;
|
||||
timeout.tv_usec = (dwMilliseconds % 1000) * 1000;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
status = select(fd + 1, &rfds, NULL, NULL, (dwMilliseconds == INFINITE) ? NULL : &timeout);
|
||||
}
|
||||
while (status < 0 && (errno == EINTR));
|
||||
#endif
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
||||
{
|
||||
ULONG Type;
|
||||
@ -256,29 +302,11 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
||||
else if (Type == HANDLE_TYPE_EVENT)
|
||||
{
|
||||
int status;
|
||||
fd_set rfds;
|
||||
WINPR_EVENT* event;
|
||||
struct timeval timeout;
|
||||
|
||||
event = (WINPR_EVENT*) Object;
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(event->pipe_fd[0], &rfds);
|
||||
ZeroMemory(&timeout, sizeof(timeout));
|
||||
|
||||
if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0))
|
||||
{
|
||||
timeout.tv_sec = dwMilliseconds / 1000;
|
||||
timeout.tv_usec = (dwMilliseconds % 1000) * 1000;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
status = select(event->pipe_fd[0] + 1, &rfds, NULL, NULL,
|
||||
(dwMilliseconds == INFINITE) ? NULL : &timeout);
|
||||
}
|
||||
while (status < 0 && (errno == EINTR));
|
||||
|
||||
status = waitOnFd(event->pipe_fd[0], dwMilliseconds);
|
||||
if (status < 0)
|
||||
{
|
||||
fprintf(stderr, "WaitForSingleObject: event select() failure [%d] %s\n", errno, strerror(errno));
|
||||
@ -299,26 +327,8 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
||||
{
|
||||
int status;
|
||||
int length;
|
||||
fd_set rfds;
|
||||
struct timeval timeout;
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(semaphore->pipe_fd[0], &rfds);
|
||||
ZeroMemory(&timeout, sizeof(timeout));
|
||||
|
||||
if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0))
|
||||
{
|
||||
timeout.tv_sec = dwMilliseconds / 1000;
|
||||
timeout.tv_usec = (dwMilliseconds % 1000) * 1000;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
status = select(semaphore->pipe_fd[0] + 1, &rfds, 0, 0,
|
||||
(dwMilliseconds == INFINITE) ? NULL : &timeout);
|
||||
}
|
||||
while (status < 0 && (errno == EINTR));
|
||||
|
||||
status = waitOnFd(semaphore->pipe_fd[0], dwMilliseconds);
|
||||
if (status < 0)
|
||||
{
|
||||
fprintf(stderr, "WaitForSingleObject: semaphore select() failure [%d] %s\n", errno, strerror(errno));
|
||||
@ -356,27 +366,9 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
||||
if (timer->fd != -1)
|
||||
{
|
||||
int status;
|
||||
fd_set rfds;
|
||||
UINT64 expirations;
|
||||
struct timeval timeout;
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(timer->fd, &rfds);
|
||||
ZeroMemory(&timeout, sizeof(timeout));
|
||||
|
||||
if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0))
|
||||
{
|
||||
timeout.tv_sec = dwMilliseconds / 1000;
|
||||
timeout.tv_usec = (dwMilliseconds % 1000) * 1000;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
status = select(timer->fd + 1, &rfds, 0, 0,
|
||||
(dwMilliseconds == INFINITE) ? NULL : &timeout);
|
||||
}
|
||||
while (status < 0 && (errno == EINTR));
|
||||
|
||||
status = waitOnFd(timer->fd, dwMilliseconds);
|
||||
if (status < 0)
|
||||
{
|
||||
fprintf(stderr, "WaitForSingleObject: timer select() failure [%d] %s\n", errno, strerror(errno));
|
||||
@ -420,8 +412,6 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
||||
{
|
||||
int fd;
|
||||
int status;
|
||||
fd_set rfds;
|
||||
struct timeval timeout;
|
||||
WINPR_NAMED_PIPE* pipe = (WINPR_NAMED_PIPE*) Object;
|
||||
|
||||
fd = (pipe->ServerMode) ? pipe->serverfd : pipe->clientfd;
|
||||
@ -432,23 +422,7 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(fd, &rfds);
|
||||
ZeroMemory(&timeout, sizeof(timeout));
|
||||
|
||||
if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0))
|
||||
{
|
||||
timeout.tv_sec = dwMilliseconds / 1000;
|
||||
timeout.tv_usec = (dwMilliseconds % 1000) * 1000;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
status = select(fd + 1, &rfds, NULL, NULL,
|
||||
(dwMilliseconds == INFINITE) ? NULL : &timeout);
|
||||
}
|
||||
while (status < 0 && (errno == EINTR));
|
||||
|
||||
status = waitOnFd(fd, dwMilliseconds);
|
||||
if (status < 0)
|
||||
{
|
||||
fprintf(stderr, "WaitForSingleObject: named pipe select() failure [%d] %s\n", errno, strerror(errno));
|
||||
@ -478,13 +452,17 @@ DWORD WaitForSingleObjectEx(HANDLE hHandle, DWORD dwMilliseconds, BOOL bAlertabl
|
||||
DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds)
|
||||
{
|
||||
int fd = -1;
|
||||
int maxfd;
|
||||
int index;
|
||||
int status;
|
||||
fd_set fds;
|
||||
ULONG Type;
|
||||
PVOID Object;
|
||||
#ifdef HAVE_POLL_H
|
||||
struct pollfd *pollfds;
|
||||
#else
|
||||
int maxfd;
|
||||
fd_set fds;
|
||||
struct timeval timeout;
|
||||
#endif
|
||||
|
||||
if (!nCount)
|
||||
{
|
||||
@ -492,10 +470,15 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
pollfds = alloca(nCount * sizeof(struct pollfd));
|
||||
#else
|
||||
maxfd = 0;
|
||||
FD_ZERO(&fds);
|
||||
ZeroMemory(&timeout, sizeof(timeout));
|
||||
|
||||
#endif
|
||||
|
||||
if (bWaitAll)
|
||||
{
|
||||
fprintf(stderr, "WaitForMultipleObjects: bWaitAll not yet implemented\n");
|
||||
@ -564,12 +547,25 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
pollfds[index].fd = fd;
|
||||
pollfds[index].events = POLLIN;
|
||||
pollfds[index].revents = 0;
|
||||
#else
|
||||
FD_SET(fd, &fds);
|
||||
|
||||
if (fd > maxfd)
|
||||
maxfd = fd;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
do
|
||||
{
|
||||
status = poll(pollfds, nCount, dwMilliseconds);
|
||||
}
|
||||
while (status < 0 && errno == EINTR);
|
||||
#else
|
||||
if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0))
|
||||
{
|
||||
timeout.tv_sec = dwMilliseconds / 1000;
|
||||
@ -582,6 +578,7 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl
|
||||
(dwMilliseconds == INFINITE) ? NULL : &timeout);
|
||||
}
|
||||
while (status < 0 && errno == EINTR);
|
||||
#endif
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
@ -615,7 +612,11 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl
|
||||
fd = (pipe->ServerMode) ? pipe->serverfd : pipe->clientfd;
|
||||
}
|
||||
|
||||
#ifdef HAVE_POLL_H
|
||||
if (pollfds[index].revents & POLLIN)
|
||||
#else
|
||||
if (FD_ISSET(fd, &fds))
|
||||
#endif
|
||||
{
|
||||
if (Type == HANDLE_TYPE_SEMAPHORE)
|
||||
{
|
||||
@ -677,3 +678,4 @@ DWORD SignalObjectAndWait(HANDLE hObjectToSignal, HANDLE hObjectToWaitOn, DWORD
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -612,7 +612,11 @@ int _select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, cons
|
||||
{
|
||||
int status;
|
||||
|
||||
status = select(nfds, readfds, writefds, exceptfds, (struct timeval*) timeout);
|
||||
do
|
||||
{
|
||||
status = select(nfds, readfds, writefds, exceptfds, (struct timeval*) timeout);
|
||||
}
|
||||
while ((status < 0) && (errno == EINTR));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user