mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-25 14:41:02 +00:00
Finish support for blocking UDP sockets
This commit is contained in:
@@ -2,13 +2,6 @@
|
||||
|
||||
#include <thread>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define poll WSAPoll
|
||||
#define SOCK_WOULDBLOCK WSAEWOULDBLOCK
|
||||
#else
|
||||
#define SOCK_WOULDBLOCK EWOULDBLOCK
|
||||
#endif
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
namespace network
|
||||
@@ -103,15 +96,20 @@ namespace network
|
||||
}
|
||||
|
||||
bool socket::set_blocking(const bool blocking)
|
||||
{
|
||||
return socket::set_blocking(this->socket_, blocking);
|
||||
}
|
||||
|
||||
bool socket::set_blocking(SOCKET s, const bool blocking)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
unsigned long mode = blocking ? 0 : 1;
|
||||
return ioctlsocket(this->socket_, FIONBIO, &mode) == 0;
|
||||
return ioctlsocket(s, FIONBIO, &mode) == 0;
|
||||
#else
|
||||
int flags = fcntl(this->socket_, F_GETFL, 0);
|
||||
int flags = fcntl(s, F_GETFL, 0);
|
||||
if (flags == -1) return false;
|
||||
flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
|
||||
return fcntl(this->socket_, F_SETFL, flags) == 0;
|
||||
return fcntl(s, F_SETFL, flags) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -200,6 +198,30 @@ namespace network
|
||||
return !socket_is_ready;
|
||||
}
|
||||
|
||||
bool socket::is_socket_ready(const SOCKET s, const bool in_poll)
|
||||
{
|
||||
pollfd pfd{};
|
||||
|
||||
pfd.fd = s;
|
||||
pfd.events = in_poll ? POLLIN : POLLOUT;
|
||||
pfd.revents = 0;
|
||||
|
||||
const auto retval = poll(&pfd, 1, 0);
|
||||
|
||||
if (retval == SOCKET_ERROR)
|
||||
{
|
||||
std::this_thread::sleep_for(1ms);
|
||||
return socket_is_ready;
|
||||
}
|
||||
|
||||
if (retval > 0)
|
||||
{
|
||||
return socket_is_ready;
|
||||
}
|
||||
|
||||
return !socket_is_ready;
|
||||
}
|
||||
|
||||
bool socket::sleep_sockets_until(const std::span<const socket*>& sockets,
|
||||
const std::chrono::high_resolution_clock::time_point time_point)
|
||||
{
|
||||
|
||||
@@ -8,12 +8,15 @@
|
||||
#ifdef _WIN32
|
||||
using socklen_t = int;
|
||||
#define GET_SOCKET_ERROR() (WSAGetLastError())
|
||||
#define poll WSAPoll
|
||||
#define SOCK_WOULDBLOCK WSAEWOULDBLOCK
|
||||
#else
|
||||
using SOCKET = int;
|
||||
using SOCKET = int;
|
||||
#define INVALID_SOCKET (SOCKET)(~0)
|
||||
#define SOCKET_ERROR (-1)
|
||||
#define GET_SOCKET_ERROR() (errno)
|
||||
#define closesocket close
|
||||
#define SOCK_WOULDBLOCK EWOULDBLOCK
|
||||
#endif
|
||||
|
||||
namespace network
|
||||
@@ -39,6 +42,7 @@ namespace network
|
||||
bool receive(address& source, std::string& data) const;
|
||||
|
||||
bool set_blocking(bool blocking);
|
||||
static bool set_blocking(SOCKET s, bool blocking);
|
||||
|
||||
static constexpr bool socket_is_ready = true;
|
||||
bool sleep(std::chrono::milliseconds timeout) const;
|
||||
@@ -53,6 +57,8 @@ namespace network
|
||||
static bool sleep_sockets_until(const std::span<const socket*>& sockets,
|
||||
std::chrono::high_resolution_clock::time_point time_point);
|
||||
|
||||
static bool is_socket_ready(SOCKET s, bool in_poll);
|
||||
|
||||
private:
|
||||
int address_family_{AF_UNSPEC};
|
||||
uint16_t port_ = 0;
|
||||
|
||||
Reference in New Issue
Block a user