Network/SocketPoller: Makes it possible to watch read and write states

This commit is contained in:
Lynix
2017-05-16 09:07:28 +02:00
parent 7425993d2d
commit 65d3b59e03
9 changed files with 192 additions and 93 deletions

View File

@@ -10,14 +10,20 @@ namespace Nz
{
void SocketPollerImpl::Clear()
{
m_activeSockets.clear();
m_readyToReadSockets.clear();
m_readyToWriteSockets.clear();
m_allSockets.clear();
m_sockets.clear();
}
bool SocketPollerImpl::IsReady(SocketHandle socket) const
bool SocketPollerImpl::IsReadyToRead(SocketHandle socket) const
{
return m_activeSockets.count(socket) != 0;
return m_readyToReadSockets.count(socket) != 0;
}
bool SocketPollerImpl::IsReadyToWrite(SocketHandle socket) const
{
return m_readyToWriteSockets.count(socket) != 0;
}
bool SocketPollerImpl::IsRegistered(SocketHandle socket) const
@@ -25,16 +31,22 @@ namespace Nz
return m_allSockets.count(socket) != 0;
}
bool SocketPollerImpl::RegisterSocket(SocketHandle socket)
bool SocketPollerImpl::RegisterSocket(SocketHandle socket, SocketPollEventFlags eventFlags)
{
NazaraAssert(!IsRegistered(socket), "Socket is already registered");
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);
@@ -57,10 +69,11 @@ 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);
}
int SocketPollerImpl::Wait(UInt64 msTimeout, SocketError* error)
@@ -68,20 +81,25 @@ namespace Nz
int activeSockets;
// 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);
m_activeSockets.clear();
if (activeSockets > 0)
m_readyToReadSockets.clear();
m_readyToWriteSockets.clear();
if (activeSockets > 0U)
{
int socketRemaining = activeSockets;
for (PollSocket& entry : m_sockets)
{
if (entry.revents & POLLRDNORM)
if (entry.revents != 0)
{
m_activeSockets.insert(entry.fd);
if (entry.revents & POLLRDNORM)
m_readyToReadSockets.insert(entry.fd);
if (entry.revents & POLLWRNORM)
m_readyToWriteSockets.insert(entry.fd);
entry.revents = 0;
if (--socketRemaining == 0)
break;
}

View File

@@ -27,13 +27,14 @@ namespace Nz
bool IsReady(SocketHandle socket) const;
bool IsRegistered(SocketHandle socket) const;
bool RegisterSocket(SocketHandle socket);
bool RegisterSocket(SocketHandle socket, SocketPollEventFlags eventFlags);
void UnregisterSocket(SocketHandle socket);
int Wait(UInt64 msTimeout, SocketError* error);
private:
std::unordered_set<SocketHandle> m_activeSockets;
std::unordered_set<SocketHandle> m_readyToReadSockets;
std::unordered_set<SocketHandle> m_readyToWriteSockets;
std::unordered_map<SocketHandle, std::size_t> m_allSockets;
std::vector<PollSocket> m_sockets;
};