Skip to content

Commit

Permalink
Windows: use select instead of WSAPoll, through a poll wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
Benjamin Sergeant committed Aug 22, 2019
1 parent c619830 commit 193da82
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 10 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Changelog
All notable changes to this project will be documented in this file.

## [5.0.5] - 2019-08-22
- Windows: use select instead of WSAPoll, through a poll wrapper

## [5.0.4] - 2019-08-20
- Windows build fixes (there was a problem with the use of ::poll that has a different name on Windows (WSAPoll))

Expand Down
77 changes: 74 additions & 3 deletions ixwebsocket/IXNetSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ namespace ix
WSADATA wsaData;
int err;

/* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
// Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h
wVersionRequested = MAKEWORD(2, 2);

err = WSAStartup(wVersionRequested, &wsaData);

return err == 0;
Expand All @@ -30,10 +29,82 @@ namespace ix
{
#ifdef _WIN32
int err = WSACleanup();

return err == 0;
#else
return true;
#endif
}

#ifdef _WIN32
//
// That function could 'return WSAPoll(pfd, nfds, timeout);'
// but WSAPoll is said to have weird behaviors on the internet
// (the curl folks have had problems with it).
//
// So we make it a select wrapper
//
int poll(struct pollfd *fds, nfds_t nfds, int timeout)
{
int maxfd = 0;
fd_set readfds, writefds, errorfds;
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_ZERO(&errorfds);

for (nfds_t i = 0; i < nfds; ++i)
{
struct pollfd *fd = &fds[i];

if (fd->fd > maxfd)
{
maxfd = fd->fd;
}
if ((fd->events & POLLIN))
{
FD_SET(fd->fd, &readfds);
}
if ((fd->events & POLLOUT))
{
FD_SET(fd->fd, &writefds);
}
if ((fd->events & POLLERR))
{
FD_SET(fd->fd, &errorfds);
}
}

struct timeval tv;
tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000;

int ret = select(maxfd + 1, &readfds, &writefds, &errorfds,
timeout != -1 ? &tv : NULL);

if (ret < 0)
{
return ret;
}

for (nfds_t i = 0; i < nfds; ++i)
{
struct pollfd *fd = &fds[i];
fd->revents = 0;

if (FD_ISSET(fd->fd, &readfds))
{
fd->revents |= POLLIN;
}
if (FD_ISSET(fd->fd, &writefds))
{
fd->revents |= POLLOUT;
}
if (FD_ISSET(fd->fd, &errorfds))
{
fd->revents |= POLLERR;
}
}

return ret;
}
#endif
}
10 changes: 5 additions & 5 deletions ixwebsocket/IXNetSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@
#include <io.h>
#include <ws2def.h>

static inline int poll(struct pollfd *pfd, unsigned long nfds, int timeout)
{
return WSAPoll(pfd, nfds, timeout);
}
// Define our own poll on Windows
typedef unsigned long int nfds_t;

int poll(struct pollfd* fds, nfds_t nfds, int timeout);

#else
#include <arpa/inet.h>
#include <errno.h>
#include <netdb.h>
#include <netinet/tcp.h>
#include <poll.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <poll.h>
#endif

namespace ix
Expand Down
2 changes: 1 addition & 1 deletion ixwebsocket/IXSocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ namespace ix
// shim to fallback to select on those platforms.
// See https://github.com/mpv-player/mpv/pull/5203/files for such a select wrapper.
//
int nfds = 1;
nfds_t nfds = 1;
struct pollfd fds[2];

fds[0].fd = sockfd;
Expand Down
2 changes: 1 addition & 1 deletion ws/ixcobra/IXCobraMetricsPublisher.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
#pragma once

#include "IXCobraMetricsThreadedPublisher.h"
#include <atomic>
#include <chrono>
#include <jsoncpp/json/json.h>
#include <string>
#include <atomic>
#include <unordered_map>

namespace ix
Expand Down

0 comments on commit 193da82

Please sign in to comment.