Skip to content
Snippets Groups Projects
Commit d0b94c03 authored by Deucе's avatar Deucе :ok_hand_tone4:
Browse files

First attempt to use poll()

There has been a sighting of Synchronet exceeding FD_SETSIZE sockets.
This means select() is of less use and we need to start migrating to
either poll() or platform-specific methods to achieve the same end.

This commit is mostly to check that poll() builds on Win32 and that
it actually works.
parent 017e0386
No related branches found
No related tags found
1 merge request!463MRC mods by Codefenix (2024-10-20)
Pipeline #1566 failed
......@@ -4,6 +4,7 @@
#include <stdlib.h>
#include <string.h>
#include "gen_defs.h"
#include "genwrap.h"
#include "sockwrap.h"
#include "dirwrap.h"
#include "multisock.h"
......@@ -255,22 +256,18 @@ static void btox(char *hexstr, const char *srcbuf, size_t srcbuflen, size_t hexs
static BOOL read_socket(SOCKET sock, char *buffer, size_t len, int (*lprintf)(int level, const char *fmt, ...))
{
fd_set socket_set;
struct timeval tv;
size_t i;
int j,rd;
unsigned char ch;
char err[128];
struct pollfd pfd;
for (i=0;i<len;i++) {
FD_ZERO(&socket_set);
FD_SET(sock,&socket_set);
pfd.fd = sock;
pfd.events = POLLIN;
pfd.revents = 0;
// We'll wait 1 secs to read from the socket.
tv.tv_sec=1;
tv.tv_usec=0;
if((j=select(sock+1,&socket_set,NULL,NULL,&tv))>0) {
if ((j = poll(&pfd, 1, 1000)) > 0) {
rd = recv(sock,&ch,1,0);
if (rd == 0) {
lprintf(LOG_WARNING,"%04d multisock read_socket() - remote closed the connection",sock);
......@@ -289,7 +286,7 @@ static BOOL read_socket(SOCKET sock, char *buffer, size_t len, int (*lprintf)(in
return FALSE;
} else {
lprintf(LOG_WARNING,"%04d multisock read_socket() - select() returned [%d] with error [%s].",sock,j,socket_strerror(socket_errno,err,sizeof(err)));
lprintf(LOG_WARNING,"%04d multisock read_socket() - poll() returned [%d] with error [%s].",sock,j,socket_strerror(socket_errno,err,sizeof(err)));
return FALSE;
}
}
......@@ -324,44 +321,50 @@ static BOOL read_socket_line(SOCKET sock, char *buffer, size_t buflen, int (*lpr
SOCKET DLLCALL xpms_accept(struct xpms_set *xpms_set, union xp_sockaddr * addr,
socklen_t * addrlen, unsigned int timeout, uint32_t flags, void **cb_data)
{
fd_set read_fs;
size_t i;
struct timeval tv;
struct timeval *tvp;
SOCKET max_sock=0;
SOCKET ret;
char hapstr[128];
char haphex[256];
char *p, *tok;
long l;
void *vp;
struct pollfd *pfds;
int timeo;
nfds_t cnt = 0;
if (xpms_set->sock_count < 1) { // Just sleep()..
SLEEP(timeout);
return INVALID_SOCKET;
}
pfds = malloc(sizeof(struct pollfd) * xpms_set->sock_count);
if (pfds == NULL)
return INVALID_SOCKET;
FD_ZERO(&read_fs);
for(i=0; i<xpms_set->sock_count; i++) {
if(xpms_set->socks[i].sock == INVALID_SOCKET)
continue;
FD_SET(xpms_set->socks[i].sock, &read_fs);
if(xpms_set->socks[i].sock >= max_sock)
max_sock=xpms_set->socks[i].sock+1;
pfds[cnt].fd = xpms_set->socks[i].sock;
pfds[cnt].events = POLLIN;
pfds[cnt].revents = 0;
cnt++;
}
if(timeout==XPMS_FOREVER)
tvp=NULL;
else {
tv.tv_sec=timeout/1000;
tv.tv_usec=(timeout%1000)*1000;
tvp=&tv;
}
switch(select(max_sock, &read_fs, NULL, NULL, tvp)) {
timeo = -1;
else
timeo = timeout;
switch(poll(pfds, cnt, timeo)) {
case 0:
return INVALID_SOCKET;
case -1:
return SOCKET_ERROR;
default:
for(i=0; i<xpms_set->sock_count; i++) {
for (i = 0, cnt = 0; i < xpms_set->sock_count; i++) {
if(xpms_set->socks[i].sock == INVALID_SOCKET)
continue;
if(FD_ISSET(xpms_set->socks[i].sock, &read_fs)) {
if (pfds[cnt++].revents & POLLIN) {
if(cb_data)
*cb_data=xpms_set->socks[i].cb_data;
ret = accept(xpms_set->socks[i].sock, &addr->addr, addrlen);
......
......@@ -64,6 +64,7 @@
#include <arpa/inet.h> /* inet_ntoa */
#include <netinet/tcp.h> /* TCP_NODELAY */
#include <unistd.h> /* close */
#include <poll.h>
#if defined(__solaris__)
#include <sys/filio.h> /* FIONBIO */
#define INADDR_NONE -1L
......@@ -172,6 +173,7 @@ static int wsa_error;
#define ERROR_VALUE ((wsa_error=WSAGetLastError())>0 ? wsa_error-WSABASEERR : wsa_error)
#define socket_errno WSAGetLastError()
#define sendsocket(s,b,l) send(s,b,l,0)
#define poll(s, c, t) WSAPoll(s, c, t)
/* For getaddrinfo() */
#ifndef AI_ADDRCONFIG
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment