2019-04-26 01:26:53 +02:00
|
|
|
/*
|
|
|
|
* IXNetSystem.cpp
|
2019-05-06 21:47:15 +02:00
|
|
|
* Author: Korchynskyi Dmytro
|
2019-04-26 01:26:53 +02:00
|
|
|
* Copyright (c) 2019 Machine Zone. All rights reserved.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "IXNetSystem.h"
|
|
|
|
|
2021-03-14 22:25:40 +01:00
|
|
|
// mingw does not have those
|
|
|
|
#if defined(_WIN32) && defined(__GNUC__)
|
2021-03-19 18:58:38 +01:00
|
|
|
const char* inet_ntop(int af, const void* src, char* dst, socklen_t size)
|
2021-03-14 22:25:40 +01:00
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2021-03-19 18:58:38 +01:00
|
|
|
int inet_pton(int af, const char* src, void* dst)
|
2021-03-14 22:25:40 +01:00
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2019-04-26 01:26:53 +02:00
|
|
|
namespace ix
|
|
|
|
{
|
|
|
|
bool initNetSystem()
|
|
|
|
{
|
|
|
|
#ifdef _WIN32
|
|
|
|
WORD wVersionRequested;
|
|
|
|
WSADATA wsaData;
|
|
|
|
int err;
|
|
|
|
|
2019-08-22 19:34:17 +02:00
|
|
|
// Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h
|
2019-04-26 01:26:53 +02:00
|
|
|
wVersionRequested = MAKEWORD(2, 2);
|
|
|
|
err = WSAStartup(wVersionRequested, &wsaData);
|
|
|
|
|
|
|
|
return err == 0;
|
|
|
|
#else
|
|
|
|
return true;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
bool uninitNetSystem()
|
|
|
|
{
|
|
|
|
#ifdef _WIN32
|
|
|
|
int err = WSACleanup();
|
|
|
|
return err == 0;
|
|
|
|
#else
|
|
|
|
return true;
|
|
|
|
#endif
|
|
|
|
}
|
2019-08-22 19:34:17 +02:00
|
|
|
|
|
|
|
//
|
|
|
|
// 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
|
|
|
|
//
|
2019-09-23 19:25:23 +02:00
|
|
|
int poll(struct pollfd* fds, nfds_t nfds, int timeout)
|
2019-08-22 19:34:17 +02:00
|
|
|
{
|
2019-09-08 20:14:49 +02:00
|
|
|
#ifdef _WIN32
|
2020-12-12 20:00:55 +01:00
|
|
|
socket_t maxfd = 0;
|
2019-08-22 19:34:17 +02:00
|
|
|
fd_set readfds, writefds, errorfds;
|
|
|
|
FD_ZERO(&readfds);
|
|
|
|
FD_ZERO(&writefds);
|
|
|
|
FD_ZERO(&errorfds);
|
|
|
|
|
|
|
|
for (nfds_t i = 0; i < nfds; ++i)
|
|
|
|
{
|
2019-09-23 19:25:23 +02:00
|
|
|
struct pollfd* fd = &fds[i];
|
2019-08-22 19:34:17 +02:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2019-09-23 19:25:23 +02:00
|
|
|
int ret = select(maxfd + 1, &readfds, &writefds, &errorfds, timeout != -1 ? &tv : NULL);
|
2019-08-22 19:34:17 +02:00
|
|
|
|
2019-09-12 20:43:52 +02:00
|
|
|
if (ret < 0)
|
2019-08-22 19:34:17 +02:00
|
|
|
{
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (nfds_t i = 0; i < nfds; ++i)
|
|
|
|
{
|
2019-09-23 19:25:23 +02:00
|
|
|
struct pollfd* fd = &fds[i];
|
2019-08-22 19:34:17 +02:00
|
|
|
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;
|
2019-09-08 20:14:49 +02:00
|
|
|
#else
|
2020-11-16 17:41:08 +01:00
|
|
|
//
|
|
|
|
// It was reported that on Android poll can fail and return -1 with
|
|
|
|
// errno == EINTR, which should be a temp error and should typically
|
|
|
|
// be handled by retrying in a loop.
|
|
|
|
// Maybe we need to put all syscall / C functions in
|
|
|
|
// a new IXSysCalls.cpp and wrap them all.
|
|
|
|
//
|
|
|
|
// The style from libuv is as such.
|
|
|
|
//
|
2020-11-16 19:14:59 +01:00
|
|
|
int ret = -1;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
ret = ::poll(fds, nfds, timeout);
|
|
|
|
} while (ret == -1 && errno == EINTR);
|
2020-11-16 17:41:08 +01:00
|
|
|
|
2020-11-16 19:14:59 +01:00
|
|
|
return ret;
|
2019-08-22 19:34:17 +02:00
|
|
|
#endif
|
2019-09-08 20:14:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace ix
|