Network/SocketPoller: Makes it possible to watch read and write states
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user