Merge pull request #9558 from iwubcode/dsu-multi-server-avoid-blocking

InputCommon: block on DSU servers collectively instead of individually
This commit is contained in:
Léo Lam 2021-03-16 10:12:32 +01:00 committed by GitHub
commit 9a3e752021
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 35 additions and 29 deletions

View File

@ -202,18 +202,6 @@ static bool IsSameController(const Proto::MessageType::PortInfo& a,
std::tie(b.pad_id, b.pad_state, b.model, b.connection_type, b.pad_mac_address); std::tie(b.pad_id, b.pad_state, b.model, b.connection_type, b.pad_mac_address);
} }
static sf::Socket::Status ReceiveWithTimeout(sf::UdpSocket& socket, void* data, std::size_t size,
std::size_t& received, sf::IpAddress& remoteAddress,
unsigned short& remotePort, sf::Time timeout)
{
sf::SocketSelector selector;
selector.add(socket);
if (selector.wait(timeout))
return socket.receive(data, size, received, remoteAddress, remotePort);
else
return sf::Socket::NotReady;
}
static void HotplugThreadFunc() static void HotplugThreadFunc()
{ {
Common::SetCurrentThreadName("DualShockUDPClient Hotplug Thread"); Common::SetCurrentThreadName("DualShockUDPClient Hotplug Thread");
@ -242,21 +230,40 @@ static void HotplugThreadFunc()
} }
} }
sf::SocketSelector selector;
for (auto& server : s_servers) for (auto& server : s_servers)
{ {
// Receive controller port info selector.add(server.m_socket);
}
using namespace std::chrono; using namespace std::chrono;
using namespace std::chrono_literals; using namespace std::chrono_literals;
Proto::Message<Proto::MessageType::FromServer> msg;
const auto timeout = s_next_listports - SteadyClock::now(); const auto timeout = s_next_listports - SteadyClock::now();
// ReceiveWithTimeout treats a timeout of zero as infinite timeout, which we don't want
// Selector's wait treats a timeout of zero as infinite timeout, which we don't want
const auto timeout_ms = std::max(duration_cast<milliseconds>(timeout), 1ms); const auto timeout_ms = std::max(duration_cast<milliseconds>(timeout), 1ms);
if (!selector.wait(sf::milliseconds(timeout_ms.count())))
{
continue;
}
for (auto& server : s_servers)
{
if (!selector.isReady(server.m_socket))
{
continue;
}
Proto::Message<Proto::MessageType::FromServer> msg;
std::size_t received_bytes; std::size_t received_bytes;
sf::IpAddress sender; sf::IpAddress sender;
u16 port; u16 port;
if (ReceiveWithTimeout(server.m_socket, &msg, sizeof(msg), received_bytes, sender, port, if (server.m_socket.receive(&msg, sizeof(msg), received_bytes, sender, port) !=
sf::milliseconds(timeout_ms.count())) == sf::Socket::Status::Done) sf::Socket::Status::Done)
{ {
continue;
}
if (auto port_info = msg.CheckAndCastTo<Proto::MessageType::PortInfo>()) if (auto port_info = msg.CheckAndCastTo<Proto::MessageType::PortInfo>())
{ {
const bool port_changed = const bool port_changed =
@ -270,7 +277,6 @@ static void HotplugThreadFunc()
} }
} }
} }
}
INFO_LOG_FMT(SERIALINTERFACE, "DualShockUDPClient hotplug thread stopped"); INFO_LOG_FMT(SERIALINTERFACE, "DualShockUDPClient hotplug thread stopped");
} }