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_AIO_H)
|
||||||
check_include_files(sys/eventfd.h HAVE_EVENTFD_H)
|
check_include_files(sys/eventfd.h HAVE_EVENTFD_H)
|
||||||
check_include_files(sys/timerfd.h HAVE_TIMERFD_H)
|
check_include_files(sys/timerfd.h HAVE_TIMERFD_H)
|
||||||
|
check_include_files(poll.h HAVE_POLL_H)
|
||||||
set(X11_FEATURE_TYPE "RECOMMENDED")
|
set(X11_FEATURE_TYPE "RECOMMENDED")
|
||||||
else()
|
else()
|
||||||
set(X11_FEATURE_TYPE "DISABLED")
|
set(X11_FEATURE_TYPE "DISABLED")
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#cmakedefine HAVE_TIMERFD_H
|
#cmakedefine HAVE_TIMERFD_H
|
||||||
#cmakedefine HAVE_TM_GMTOFF
|
#cmakedefine HAVE_TM_GMTOFF
|
||||||
#cmakedefine HAVE_AIO_H
|
#cmakedefine HAVE_AIO_H
|
||||||
|
#cmakedefine HAVE_POLL_H
|
||||||
#cmakedefine HAVE_PTHREAD_GNU_EXT
|
#cmakedefine HAVE_PTHREAD_GNU_EXT
|
||||||
#cmakedefine HAVE_VALGRIND_MEMCHECK_H
|
#cmakedefine HAVE_VALGRIND_MEMCHECK_H
|
||||||
|
|
||||||
|
@ -41,6 +41,13 @@
|
|||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_POLL_H
|
||||||
|
#include <poll.h>
|
||||||
|
#else
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
#ifndef SOL_TCP
|
#ifndef SOL_TCP
|
||||||
#define SOL_TCP IPPROTO_TCP
|
#define SOL_TCP IPPROTO_TCP
|
||||||
@ -739,6 +746,83 @@ HANDLE tcp_get_event_handle(rdpTcp* tcp)
|
|||||||
#endif
|
#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_new(rdpSettings* settings)
|
||||||
{
|
{
|
||||||
rdpTcp* tcp;
|
rdpTcp* tcp;
|
||||||
|
@ -64,8 +64,8 @@ BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeout);
|
|||||||
BOOL tcp_disconnect(rdpTcp* tcp);
|
BOOL tcp_disconnect(rdpTcp* tcp);
|
||||||
int tcp_read(rdpTcp* tcp, BYTE* data, int length);
|
int tcp_read(rdpTcp* tcp, BYTE* data, int length);
|
||||||
int tcp_write(rdpTcp* tcp, BYTE* data, int length);
|
int tcp_write(rdpTcp* tcp, BYTE* data, int length);
|
||||||
int tcp_wait_read(rdpTcp* tcp);
|
int tcp_wait_read(rdpTcp* tcp, DWORD dwMilliSeconds);
|
||||||
int tcp_wait_write(rdpTcp* tcp);
|
int tcp_wait_write(rdpTcp* tcp, DWORD dwMilliSeconds);
|
||||||
BOOL tcp_set_blocking_mode(rdpTcp* tcp, BOOL blocking);
|
BOOL tcp_set_blocking_mode(rdpTcp* tcp, BOOL blocking);
|
||||||
BOOL tcp_set_keep_alive_mode(rdpTcp* tcp);
|
BOOL tcp_set_keep_alive_mode(rdpTcp* tcp);
|
||||||
int tcp_attach(rdpTcp* tcp, int sockfd);
|
int tcp_attach(rdpTcp* tcp, int sockfd);
|
||||||
|
@ -43,9 +43,7 @@
|
|||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/select.h>
|
#endif /* _WIN32 */
|
||||||
#include <sys/time.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_VALGRIND_MEMCHECK_H
|
#ifdef HAVE_VALGRIND_MEMCHECK_H
|
||||||
#include <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)
|
static int transport_wait_for_read(rdpTransport* transport)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
rdpTcp *tcpIn = transport->TcpIn;
|
||||||
fd_set rset, wset;
|
|
||||||
fd_set *rsetPtr = NULL, *wsetPtr = NULL;
|
|
||||||
rdpTcp *tcpIn;
|
|
||||||
|
|
||||||
tcpIn = transport->TcpIn;
|
|
||||||
|
|
||||||
if (tcpIn->readBlocked)
|
if (tcpIn->readBlocked)
|
||||||
{
|
{
|
||||||
rsetPtr = &rset;
|
return tcp_wait_read(tcpIn, 1000);
|
||||||
FD_ZERO(rsetPtr);
|
|
||||||
FD_SET(tcpIn->sockfd, rsetPtr);
|
|
||||||
}
|
}
|
||||||
else if (tcpIn->writeBlocked)
|
else if (tcpIn->writeBlocked)
|
||||||
{
|
{
|
||||||
wsetPtr = &wset;
|
return tcp_wait_write(tcpIn, 1000);
|
||||||
FD_ZERO(wsetPtr);
|
|
||||||
FD_SET(tcpIn->sockfd, wsetPtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wsetPtr && !rsetPtr)
|
USleep(1000);
|
||||||
{
|
return 0;
|
||||||
USleep(1000);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
tv.tv_sec = 0;
|
|
||||||
tv.tv_usec = 1000;
|
|
||||||
|
|
||||||
return select(tcpIn->sockfd + 1, rsetPtr, wsetPtr, NULL, &tv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int transport_wait_for_write(rdpTransport* transport)
|
static int transport_wait_for_write(rdpTransport* transport)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
|
||||||
fd_set rset, wset;
|
|
||||||
fd_set *rsetPtr = NULL, *wsetPtr = NULL;
|
|
||||||
rdpTcp *tcpOut;
|
rdpTcp *tcpOut;
|
||||||
|
|
||||||
tcpOut = transport->SplitInputOutput ? transport->TcpOut : transport->TcpIn;
|
tcpOut = transport->SplitInputOutput ? transport->TcpOut : transport->TcpIn;
|
||||||
if (tcpOut->writeBlocked)
|
if (tcpOut->writeBlocked)
|
||||||
{
|
{
|
||||||
wsetPtr = &wset;
|
return tcp_wait_write(tcpOut, 1000);
|
||||||
FD_ZERO(wsetPtr);
|
|
||||||
FD_SET(tcpOut->sockfd, wsetPtr);
|
|
||||||
}
|
}
|
||||||
else if (tcpOut->readBlocked)
|
else if (tcpOut->readBlocked)
|
||||||
{
|
{
|
||||||
rsetPtr = &rset;
|
return tcp_wait_read(tcpOut, 1000);
|
||||||
FD_ZERO(rsetPtr);
|
|
||||||
FD_SET(tcpOut->sockfd, rsetPtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wsetPtr && !rsetPtr)
|
USleep(1000);
|
||||||
{
|
return 0;
|
||||||
USleep(1000);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
tv.tv_sec = 0;
|
|
||||||
tv.tv_usec = 1000;
|
|
||||||
|
|
||||||
return select(tcpOut->sockfd + 1, rsetPtr, wsetPtr, NULL, &tv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int transport_read_layer(rdpTransport* transport, BYTE* data, int bytes)
|
int transport_read_layer(rdpTransport* transport, BYTE* data, int bytes)
|
||||||
|
@ -33,6 +33,11 @@
|
|||||||
#include <freerdp/crypto/tls.h>
|
#include <freerdp/crypto/tls.h>
|
||||||
#include "../core/tcp.h"
|
#include "../core/tcp.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_POLL_H
|
||||||
|
#include <poll.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct _BIO_RDP_TLS
|
struct _BIO_RDP_TLS
|
||||||
{
|
{
|
||||||
SSL* ssl;
|
SSL* ssl;
|
||||||
@ -586,8 +591,12 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode)
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_POLL_H
|
||||||
|
struct pollfd pollfds;
|
||||||
|
#else
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
fd_set rset;
|
fd_set rset;
|
||||||
|
#endif
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
status = BIO_do_handshake(tls->bio);
|
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
|
/* we select() only for read even if we should test both read and write
|
||||||
* depending of what have blocked */
|
* depending of what have blocked */
|
||||||
FD_ZERO(&rset);
|
|
||||||
|
|
||||||
fd = BIO_get_fd(tls->bio, NULL);
|
fd = BIO_get_fd(tls->bio, NULL);
|
||||||
|
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
@ -610,12 +617,24 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode)
|
|||||||
return -1;
|
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);
|
FD_SET(fd, &rset);
|
||||||
tv.tv_sec = 0;
|
tv.tv_sec = 0;
|
||||||
tv.tv_usec = 10 * 1000; /* 10ms */
|
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)
|
if (status < 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: error during select()\n", __FUNCTION__);
|
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;
|
int status, nchunks, commitedBytes;
|
||||||
rdpTcp *tcp;
|
rdpTcp *tcp;
|
||||||
|
#ifdef HAVE_POLL_H
|
||||||
|
struct pollfd pollfds;
|
||||||
|
#else
|
||||||
fd_set rset, wset;
|
fd_set rset, wset;
|
||||||
fd_set *rsetPtr, *wsetPtr;
|
fd_set *rsetPtr, *wsetPtr;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
#endif
|
||||||
BIO* bio = tls->bio;
|
BIO* bio = tls->bio;
|
||||||
DataChunk chunks[2];
|
DataChunk chunks[2];
|
||||||
|
|
||||||
@ -855,9 +878,34 @@ int tls_write_all(rdpTls* tls, const BYTE* data, int length)
|
|||||||
|
|
||||||
if (!BIO_should_retry(bio))
|
if (!BIO_should_retry(bio))
|
||||||
return -1;
|
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 */
|
/* we try to handle SSL want_read and want_write nicely */
|
||||||
rsetPtr = wsetPtr = 0;
|
rsetPtr = wsetPtr = NULL;
|
||||||
|
|
||||||
if (tcp->writeBlocked)
|
if (tcp->writeBlocked)
|
||||||
{
|
{
|
||||||
@ -881,8 +929,8 @@ int tls_write_all(rdpTls* tls, const BYTE* data, int length)
|
|||||||
tv.tv_sec = 0;
|
tv.tv_sec = 0;
|
||||||
tv.tv_usec = 100 * 1000;
|
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)
|
if (status < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -911,13 +959,24 @@ int tls_write_all(rdpTls* tls, const BYTE* data, int length)
|
|||||||
if (!BIO_should_retry(tcp->socketBio))
|
if (!BIO_should_retry(tcp->socketBio))
|
||||||
goto out_fail;
|
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_ZERO(&rset);
|
||||||
FD_SET(tcp->sockfd, &rset);
|
FD_SET(tcp->sockfd, &rset);
|
||||||
tv.tv_sec = 0;
|
tv.tv_sec = 0;
|
||||||
tv.tv_usec = 100 * 1000;
|
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)
|
if (status < 0)
|
||||||
goto out_fail;
|
goto out_fail;
|
||||||
}
|
}
|
||||||
|
@ -41,11 +41,16 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/select.h>
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_POLL_H
|
||||||
|
#include <poll.h>
|
||||||
|
#else
|
||||||
|
#include <sys/select.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#ifndef TCP_KEEPIDLE
|
#ifndef TCP_KEEPIDLE
|
||||||
#define TCP_KEEPIDLE TCP_KEEPALIVE
|
#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 freerdp_tcp_wait_read(int sockfd)
|
||||||
{
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
#ifdef HAVE_POLL_H
|
||||||
|
struct pollfd pollfds;
|
||||||
|
#else
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (sockfd < 1)
|
if (sockfd < 1)
|
||||||
{
|
{
|
||||||
@ -195,37 +206,61 @@ int freerdp_tcp_wait_read(int sockfd)
|
|||||||
return 0 ;
|
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_ZERO(&fds);
|
||||||
FD_SET(sockfd, &fds);
|
FD_SET(sockfd, &fds);
|
||||||
timeout.tv_sec = 5;
|
timeout.tv_sec = 5;
|
||||||
timeout.tv_usec = 0;
|
timeout.tv_usec = 0;
|
||||||
select(sockfd+1, &fds, NULL, NULL, &timeout);
|
status = _select(sockfd+1, &fds, NULL, NULL, &timeout);
|
||||||
if (!FD_ISSET(sockfd, &fds))
|
#endif
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
return status > 0 ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int freerdp_tcp_wait_write(int sockfd)
|
int freerdp_tcp_wait_write(int sockfd)
|
||||||
{
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
#ifdef HAVE_POLL_H
|
||||||
|
struct pollfd pollfds;
|
||||||
|
#else
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (sockfd < 1)
|
if (sockfd < 1)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Invalid socket to watch: %d\n", sockfd);
|
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_ZERO(&fds);
|
||||||
FD_SET(sockfd, &fds);
|
FD_SET(sockfd, &fds);
|
||||||
timeout.tv_sec = 5;
|
timeout.tv_sec = 5;
|
||||||
timeout.tv_usec = 0;
|
timeout.tv_usec = 0;
|
||||||
select(sockfd+1, NULL, &fds, NULL, &timeout);
|
status = _select(sockfd+1, NULL, &fds, NULL, &timeout);
|
||||||
if (!FD_ISSET(sockfd, &fds))
|
#endif
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
return status > 0 ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int freerdp_tcp_disconnect(int sockfd)
|
int freerdp_tcp_disconnect(int sockfd)
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
* Synchronization Functions
|
* Synchronization Functions
|
||||||
*
|
*
|
||||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
* 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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -25,6 +26,10 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_POLL_H
|
||||||
|
#include <poll.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.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;
|
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)
|
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
||||||
{
|
{
|
||||||
ULONG Type;
|
ULONG Type;
|
||||||
@ -256,29 +302,11 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
|||||||
else if (Type == HANDLE_TYPE_EVENT)
|
else if (Type == HANDLE_TYPE_EVENT)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
fd_set rfds;
|
|
||||||
WINPR_EVENT* event;
|
WINPR_EVENT* event;
|
||||||
struct timeval timeout;
|
|
||||||
|
|
||||||
event = (WINPR_EVENT*) Object;
|
event = (WINPR_EVENT*) Object;
|
||||||
|
|
||||||
FD_ZERO(&rfds);
|
status = waitOnFd(event->pipe_fd[0], dwMilliseconds);
|
||||||
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));
|
|
||||||
|
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "WaitForSingleObject: event select() failure [%d] %s\n", errno, strerror(errno));
|
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 status;
|
||||||
int length;
|
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)
|
if (status < 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "WaitForSingleObject: semaphore select() failure [%d] %s\n", errno, strerror(errno));
|
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)
|
if (timer->fd != -1)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
fd_set rfds;
|
|
||||||
UINT64 expirations;
|
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)
|
if (status < 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "WaitForSingleObject: timer select() failure [%d] %s\n", errno, strerror(errno));
|
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 fd;
|
||||||
int status;
|
int status;
|
||||||
fd_set rfds;
|
|
||||||
struct timeval timeout;
|
|
||||||
WINPR_NAMED_PIPE* pipe = (WINPR_NAMED_PIPE*) Object;
|
WINPR_NAMED_PIPE* pipe = (WINPR_NAMED_PIPE*) Object;
|
||||||
|
|
||||||
fd = (pipe->ServerMode) ? pipe->serverfd : pipe->clientfd;
|
fd = (pipe->ServerMode) ? pipe->serverfd : pipe->clientfd;
|
||||||
@ -432,23 +422,7 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
|||||||
return WAIT_FAILED;
|
return WAIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
FD_ZERO(&rfds);
|
status = waitOnFd(fd, dwMilliseconds);
|
||||||
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));
|
|
||||||
|
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "WaitForSingleObject: named pipe select() failure [%d] %s\n", errno, strerror(errno));
|
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)
|
DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds)
|
||||||
{
|
{
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
int maxfd;
|
|
||||||
int index;
|
int index;
|
||||||
int status;
|
int status;
|
||||||
fd_set fds;
|
|
||||||
ULONG Type;
|
ULONG Type;
|
||||||
PVOID Object;
|
PVOID Object;
|
||||||
|
#ifdef HAVE_POLL_H
|
||||||
|
struct pollfd *pollfds;
|
||||||
|
#else
|
||||||
|
int maxfd;
|
||||||
|
fd_set fds;
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!nCount)
|
if (!nCount)
|
||||||
{
|
{
|
||||||
@ -492,10 +470,15 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl
|
|||||||
return WAIT_FAILED;
|
return WAIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_POLL_H
|
||||||
|
pollfds = alloca(nCount * sizeof(struct pollfd));
|
||||||
|
#else
|
||||||
maxfd = 0;
|
maxfd = 0;
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
ZeroMemory(&timeout, sizeof(timeout));
|
ZeroMemory(&timeout, sizeof(timeout));
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
if (bWaitAll)
|
if (bWaitAll)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "WaitForMultipleObjects: bWaitAll not yet implemented\n");
|
fprintf(stderr, "WaitForMultipleObjects: bWaitAll not yet implemented\n");
|
||||||
@ -564,12 +547,25 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl
|
|||||||
return WAIT_FAILED;
|
return WAIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_POLL_H
|
||||||
|
pollfds[index].fd = fd;
|
||||||
|
pollfds[index].events = POLLIN;
|
||||||
|
pollfds[index].revents = 0;
|
||||||
|
#else
|
||||||
FD_SET(fd, &fds);
|
FD_SET(fd, &fds);
|
||||||
|
|
||||||
if (fd > maxfd)
|
if (fd > maxfd)
|
||||||
maxfd = fd;
|
maxfd = fd;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_POLL_H
|
||||||
|
do
|
||||||
|
{
|
||||||
|
status = poll(pollfds, nCount, dwMilliseconds);
|
||||||
|
}
|
||||||
|
while (status < 0 && errno == EINTR);
|
||||||
|
#else
|
||||||
if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0))
|
if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0))
|
||||||
{
|
{
|
||||||
timeout.tv_sec = dwMilliseconds / 1000;
|
timeout.tv_sec = dwMilliseconds / 1000;
|
||||||
@ -582,6 +578,7 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl
|
|||||||
(dwMilliseconds == INFINITE) ? NULL : &timeout);
|
(dwMilliseconds == INFINITE) ? NULL : &timeout);
|
||||||
}
|
}
|
||||||
while (status < 0 && errno == EINTR);
|
while (status < 0 && errno == EINTR);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
{
|
{
|
||||||
@ -615,7 +612,11 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl
|
|||||||
fd = (pipe->ServerMode) ? pipe->serverfd : pipe->clientfd;
|
fd = (pipe->ServerMode) ? pipe->serverfd : pipe->clientfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_POLL_H
|
||||||
|
if (pollfds[index].revents & POLLIN)
|
||||||
|
#else
|
||||||
if (FD_ISSET(fd, &fds))
|
if (FD_ISSET(fd, &fds))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if (Type == HANDLE_TYPE_SEMAPHORE)
|
if (Type == HANDLE_TYPE_SEMAPHORE)
|
||||||
{
|
{
|
||||||
@ -677,3 +678,4 @@ DWORD SignalObjectAndWait(HANDLE hObjectToSignal, HANDLE hObjectToWaitOn, DWORD
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -612,7 +612,11 @@ int _select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, cons
|
|||||||
{
|
{
|
||||||
int status;
|
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;
|
return status;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user