// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Network module" // For conditions of distribution and use, see copyright notice in Config.hpp #include #include #include namespace Nz { void SocketPollerImpl::Clear() { m_readyToReadSockets.clear(); m_readyToWriteSockets.clear(); m_allSockets.clear(); m_sockets.clear(); } bool SocketPollerImpl::IsReadyToRead(SocketHandle socket) const { return m_readyToReadSockets.count(socket) != 0; } bool SocketPollerImpl::IsReadyToWrite(SocketHandle socket) const { return m_readyToWriteSockets.count(socket) != 0; } bool SocketPollerImpl::IsRegistered(SocketHandle socket) const { return m_allSockets.count(socket) != 0; } bool SocketPollerImpl::RegisterSocket(SocketHandle socket, SocketPollEventFlags eventFlags) { NazaraAssert(!IsRegistered(socket), "Socket is already registered"); PollSocket entry = { socket, 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); return true; } void SocketPollerImpl::UnregisterSocket(SocketHandle socket) { NazaraAssert(IsRegistered(socket), "Socket is not registered"); if (m_sockets.size() > 1U) { // Instead of using vector::erase, let's move the last element to the now unoccupied position std::size_t entry = m_allSockets[socket]; // Get the last element and update it's position const PollSocket& lastElement = m_sockets.back(); m_allSockets[lastElement.fd] = entry; // 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_allSockets.erase(socket); m_readyToReadSockets.erase(socket); m_readyToWriteSockets.erase(socket); } int SocketPollerImpl::Wait(int msTimeout, SocketError* error) { int activeSockets; // Reset status of sockets activeSockets = SocketImpl::Poll(m_sockets.data(), m_sockets.size(), static_cast(msTimeout), error); m_readyToReadSockets.clear(); m_readyToWriteSockets.clear(); if (activeSockets > 0U) { int socketRemaining = activeSockets; for (PollSocket& entry : m_sockets) { if (entry.revents != 0) { 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; } } } return activeSockets; } }