Network/SocketPoller: Makes it possible to watch read and write states
This commit is contained in:
@@ -10,29 +10,43 @@ namespace Nz
|
||||
SocketPollerImpl::SocketPollerImpl()
|
||||
{
|
||||
#if !NAZARA_NETWORK_POLL_SUPPORT
|
||||
FD_ZERO(&m_activeSockets);
|
||||
FD_ZERO(&m_sockets);
|
||||
FD_ZERO(&m_readSockets);
|
||||
FD_ZERO(&m_readyToReadSockets);
|
||||
FD_ZERO(&m_readyToWriteSockets);
|
||||
FD_ZERO(&m_writeSockets);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SocketPollerImpl::Clear()
|
||||
{
|
||||
#if NAZARA_NETWORK_POLL_SUPPORT
|
||||
m_activeSockets.clear();
|
||||
m_allSockets.clear();
|
||||
m_readyToReadSockets.clear();
|
||||
m_readyToWriteSockets.clear();
|
||||
m_sockets.clear();
|
||||
#else
|
||||
FD_ZERO(&m_activeSockets);
|
||||
FD_ZERO(&m_sockets);
|
||||
FD_ZERO(&m_readSockets);
|
||||
FD_ZERO(&m_readyToReadSockets);
|
||||
FD_ZERO(&m_readyToWriteSockets);
|
||||
FD_ZERO(&m_writeSockets);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SocketPollerImpl::IsReady(SocketHandle socket) const
|
||||
bool SocketPollerImpl::IsReadyToRead(SocketHandle socket) const
|
||||
{
|
||||
#if NAZARA_NETWORK_POLL_SUPPORT
|
||||
return m_activeSockets.count(socket) != 0;
|
||||
return m_readyToReadSockets.count(socket) != 0;
|
||||
#else
|
||||
return FD_ISSET(socket, &m_activeSockets) != 0;
|
||||
return FD_ISSET(socket, &m_readyToReadSockets) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SocketPollerImpl::IsReadyToWrite(SocketHandle socket) const
|
||||
{
|
||||
#if NAZARA_NETWORK_POLL_SUPPORT
|
||||
return m_readyToWriteSockets.count(socket) != 0;
|
||||
#else
|
||||
return FD_ISSET(socket, &m_readyToWriteSockets) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -41,31 +55,45 @@ namespace Nz
|
||||
#if NAZARA_NETWORK_POLL_SUPPORT
|
||||
return m_allSockets.count(socket) != 0;
|
||||
#else
|
||||
return FD_ISSET(socket, &m_sockets) != 0;
|
||||
return FD_ISSET(socket, &m_readSockets) != 0 ||
|
||||
FD_ISSET(socket, &m_writeSockets) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SocketPollerImpl::RegisterSocket(SocketHandle socket)
|
||||
bool SocketPollerImpl::RegisterSocket(SocketHandle socket, SocketPollEventFlags eventFlags)
|
||||
{
|
||||
NazaraAssert(!IsRegistered(socket), "Socket is already registered");
|
||||
|
||||
#if NAZARA_NETWORK_POLL_SUPPORT
|
||||
PollSocket entry = {
|
||||
socket,
|
||||
POLLRDNORM,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
if (eventFlags & SocketPollEvent_Read)
|
||||
entry.events |= POLLRDNORM;
|
||||
|
||||
if (eventFlags & SocketPollEvent_Write)
|
||||
entry.events |= POLLWRNORM;
|
||||
|
||||
m_allSockets[socket] = m_sockets.size();
|
||||
m_sockets.emplace_back(entry);
|
||||
#else
|
||||
if (m_sockets.fd_count > FD_SETSIZE)
|
||||
for (std::size_t i = 0; i < 2; ++i)
|
||||
{
|
||||
NazaraError("Socket count exceeding FD_SETSIZE (" + String::Number(FD_SETSIZE) + ")");
|
||||
return false;
|
||||
}
|
||||
if (eventFlags & ((i == 0) ? SocketPollEvent_Read : SocketPollEvent_Write) == 0)
|
||||
continue;
|
||||
|
||||
FD_SET(socket, &m_sockets);
|
||||
fd_set& targetSet = (i == 0) ? m_readSockets : m_writeSockets;
|
||||
if (targetSet.fd_count > FD_SETSIZE)
|
||||
{
|
||||
NazaraError("Socket count exceeding hard-coded FD_SETSIZE (" + String::Number(FD_SETSIZE) + ")");
|
||||
return false;
|
||||
}
|
||||
|
||||
FD_SET(socket, &targetSet);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
@@ -88,13 +116,16 @@ namespace Nz
|
||||
// Now move it properly (lastElement is invalid after the following line) and pop it
|
||||
m_sockets[entry] = std::move(m_sockets.back());
|
||||
}
|
||||
|
||||
m_sockets.pop_back();
|
||||
m_activeSockets.erase(socket);
|
||||
|
||||
m_allSockets.erase(socket);
|
||||
m_readyToReadSockets.erase(socket);
|
||||
m_readyToWriteSockets.erase(socket);
|
||||
#else
|
||||
FD_CLR(socket, &m_activeSockets);
|
||||
FD_CLR(socket, &m_sockets);
|
||||
FD_CLR(socket, &m_readSockets);
|
||||
FD_CLR(socket, &m_readyToReadSockets);
|
||||
FD_CLR(socket, &m_readyToWriteSockets);
|
||||
FD_CLR(socket, &m_writeSockets);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -103,35 +134,18 @@ namespace Nz
|
||||
int activeSockets;
|
||||
|
||||
#if NAZARA_NETWORK_POLL_SUPPORT
|
||||
// Reset status of sockets
|
||||
for (PollSocket& entry : m_sockets)
|
||||
entry.revents = 0;
|
||||
|
||||
activeSockets = SocketImpl::Poll(m_sockets.data(), m_sockets.size(), static_cast<int>(msTimeout), error);
|
||||
x
|
||||
|
||||
m_activeSockets.clear();
|
||||
if (activeSockets > 0U)
|
||||
{
|
||||
int socketRemaining = activeSockets;
|
||||
for (PollSocket& entry : m_sockets)
|
||||
{
|
||||
if (entry.revents & POLLRDNORM)
|
||||
{
|
||||
m_activeSockets.insert(entry.fd);
|
||||
if (--socketRemaining == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
m_activeSockets = m_sockets;
|
||||
m_readyToReadSockets = m_readSockets;
|
||||
m_readyToWriteSockets = m_writeSockets;
|
||||
|
||||
timeval tv;
|
||||
tv.tv_sec = static_cast<long>(msTimeout / 1000ULL);
|
||||
tv.tv_usec = static_cast<long>((msTimeout % 1000ULL) * 1000ULL);
|
||||
|
||||
activeSockets = ::select(0xDEADBEEF, &m_activeSockets, nullptr, nullptr, (msTimeout > 0) ? &tv : nullptr); //< The first argument is ignored on Windows
|
||||
activeSockets = ::select(0xDEADBEEF, &m_readyToReadSockets, &m_readyToWriteSockets, nullptr, (msTimeout > 0) ? &tv : nullptr); //< The first argument is ignored on Windows
|
||||
if (activeSockets == SOCKET_ERROR)
|
||||
{
|
||||
if (error)
|
||||
|
||||
Reference in New Issue
Block a user