mirror of
https://github.com/SFML/SFML.git
synced 2024-12-01 15:51:04 +08:00
Merge branch 'bugfix/socket_selector'
This commit is contained in:
commit
b96d330b9f
@ -29,6 +29,7 @@
|
|||||||
#include <SFML/Network/Socket.hpp>
|
#include <SFML/Network/Socket.hpp>
|
||||||
#include <SFML/Network/SocketImpl.hpp>
|
#include <SFML/Network/SocketImpl.hpp>
|
||||||
#include <SFML/System/Err.hpp>
|
#include <SFML/System/Err.hpp>
|
||||||
|
#include <algorithm>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@ -41,9 +42,10 @@ namespace sf
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
struct SocketSelector::SocketSelectorImpl
|
struct SocketSelector::SocketSelectorImpl
|
||||||
{
|
{
|
||||||
fd_set AllSockets; ///< Set containing all the sockets handles
|
fd_set allSockets; ///< Set containing all the sockets handles
|
||||||
fd_set SocketsReady; ///< Set containing handles of the sockets that are ready
|
fd_set socketsReady; ///< Set containing handles of the sockets that are ready
|
||||||
int MaxSocket; ///< Maximum socket handle
|
int maxSocket; ///< Maximum socket handle
|
||||||
|
int socketCount; ///< Number of socket handles
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -76,20 +78,38 @@ void SocketSelector::add(Socket& socket)
|
|||||||
SocketHandle handle = socket.getHandle();
|
SocketHandle handle = socket.getHandle();
|
||||||
if (handle != priv::SocketImpl::invalidSocket())
|
if (handle != priv::SocketImpl::invalidSocket())
|
||||||
{
|
{
|
||||||
if (handle < FD_SETSIZE)
|
|
||||||
{
|
|
||||||
FD_SET(handle, &m_impl->AllSockets);
|
|
||||||
|
|
||||||
int size = static_cast<int>(handle);
|
#if defined(SFML_SYSTEM_WINDOWS)
|
||||||
if (size > m_impl->MaxSocket)
|
|
||||||
m_impl->MaxSocket = size;
|
if (m_impl->socketCount >= FD_SETSIZE)
|
||||||
|
{
|
||||||
|
err() << "The socket can't be added to the selector because the "
|
||||||
|
<< "selector is full. This is a limitation of your operating "
|
||||||
|
<< "system's FD_SETSIZE setting.";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (FD_ISSET(handle, &m_impl->allSockets))
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_impl->socketCount++;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
if (handle >= FD_SETSIZE)
|
||||||
{
|
{
|
||||||
err() << "The socket can't be added to the selector because its "
|
err() << "The socket can't be added to the selector because its "
|
||||||
<< "ID is too high. This is a limitation of your operating "
|
<< "ID is too high. This is a limitation of your operating "
|
||||||
<< "system's FD_SETSIZE setting.";
|
<< "system's FD_SETSIZE setting.";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SocketHandle is an int in POSIX
|
||||||
|
m_impl->maxSocket = std::max(m_impl->maxSocket, handle);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FD_SET(handle, &m_impl->allSockets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,18 +117,38 @@ void SocketSelector::add(Socket& socket)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void SocketSelector::remove(Socket& socket)
|
void SocketSelector::remove(Socket& socket)
|
||||||
{
|
{
|
||||||
FD_CLR(socket.getHandle(), &m_impl->AllSockets);
|
SocketHandle handle = socket.getHandle();
|
||||||
FD_CLR(socket.getHandle(), &m_impl->SocketsReady);
|
if (handle != priv::SocketImpl::invalidSocket())
|
||||||
|
{
|
||||||
|
|
||||||
|
#if defined(SFML_SYSTEM_WINDOWS)
|
||||||
|
|
||||||
|
if (!FD_ISSET(handle, &m_impl->allSockets))
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_impl->socketCount--;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
if (handle >= FD_SETSIZE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FD_CLR(handle, &m_impl->allSockets);
|
||||||
|
FD_CLR(handle, &m_impl->socketsReady);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void SocketSelector::clear()
|
void SocketSelector::clear()
|
||||||
{
|
{
|
||||||
FD_ZERO(&m_impl->AllSockets);
|
FD_ZERO(&m_impl->allSockets);
|
||||||
FD_ZERO(&m_impl->SocketsReady);
|
FD_ZERO(&m_impl->socketsReady);
|
||||||
|
|
||||||
m_impl->MaxSocket = 0;
|
m_impl->maxSocket = 0;
|
||||||
|
m_impl->socketCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -121,10 +161,11 @@ bool SocketSelector::wait(Time timeout)
|
|||||||
time.tv_usec = static_cast<long>(timeout.asMicroseconds() % 1000000);
|
time.tv_usec = static_cast<long>(timeout.asMicroseconds() % 1000000);
|
||||||
|
|
||||||
// Initialize the set that will contain the sockets that are ready
|
// Initialize the set that will contain the sockets that are ready
|
||||||
m_impl->SocketsReady = m_impl->AllSockets;
|
m_impl->socketsReady = m_impl->allSockets;
|
||||||
|
|
||||||
// Wait until one of the sockets is ready for reading, or timeout is reached
|
// Wait until one of the sockets is ready for reading, or timeout is reached
|
||||||
int count = select(m_impl->MaxSocket + 1, &m_impl->SocketsReady, NULL, NULL, timeout != Time::Zero ? &time : NULL);
|
// The first parameter is ignored on Windows
|
||||||
|
int count = select(m_impl->maxSocket + 1, &m_impl->socketsReady, NULL, NULL, timeout != Time::Zero ? &time : NULL);
|
||||||
|
|
||||||
return count > 0;
|
return count > 0;
|
||||||
}
|
}
|
||||||
@ -133,7 +174,21 @@ bool SocketSelector::wait(Time timeout)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool SocketSelector::isReady(Socket& socket) const
|
bool SocketSelector::isReady(Socket& socket) const
|
||||||
{
|
{
|
||||||
return FD_ISSET(socket.getHandle(), &m_impl->SocketsReady) != 0;
|
SocketHandle handle = socket.getHandle();
|
||||||
|
if (handle != priv::SocketImpl::invalidSocket())
|
||||||
|
{
|
||||||
|
|
||||||
|
#if !defined(SFML_SYSTEM_WINDOWS)
|
||||||
|
|
||||||
|
if (handle >= FD_SETSIZE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return FD_ISSET(handle, &m_impl->socketsReady) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user