From a8ecf9e383c948815c58b41d035840dae9769242 Mon Sep 17 00:00:00 2001 From: Sepalani Date: Sun, 22 Feb 2026 03:17:11 +0400 Subject: [PATCH] AMMediaboard: Fix setsockopt timeout parameters --- Source/Core/Core/HW/DVD/AMMediaboard.cpp | 36 +++++++++++++++++++----- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/Source/Core/Core/HW/DVD/AMMediaboard.cpp b/Source/Core/Core/HW/DVD/AMMediaboard.cpp index 1b653d87f0..cd7e0e7240 100644 --- a/Source/Core/Core/HW/DVD/AMMediaboard.cpp +++ b/Source/Core/Core/HW/DVD/AMMediaboard.cpp @@ -1738,16 +1738,28 @@ u32 ExecuteCommand(std::array& dicmd_buf, u32* diimm_buf, u32 address, u const u32 timeout_b = s_media_buffer_32[4]; const u32 timeout_c = s_media_buffer_32[5]; - s_timeouts[0] = timeout_a; - s_timeouts[1] = timeout_b; - s_timeouts[2] = timeout_c; + s_timeouts[0] = timeout_a; // connect timeout? + s_timeouts[1] = timeout_b; // send timeout? + s_timeouts[2] = timeout_c; // recv timeout? int ret = SOCKET_ERROR; + // Workaround for Linux/Windows socket timeout option. + constexpr auto socket_timeout = [](u32 timeout_ms) { +#ifdef _WIN32 + return static_cast(timeout_ms); +#else + return timeval{.tv_sec = s32(timeout_ms / 1000), + .tv_usec = s32(timeout_ms % 1000) * 1000}; +#endif + }; + const auto timeval_b{socket_timeout(timeout_b)}; + const auto timeval_c{socket_timeout(timeout_c)}; + if (host_socket != INVALID_SOCKET) { ret = setsockopt(host_socket, SOL_SOCKET, SO_SNDTIMEO, - reinterpret_cast(&timeout_b), sizeof(int)); + reinterpret_cast(&timeval_b), sizeof(timeval_b)); if (ret < 0) { ret = WSAGetLastError(); @@ -1755,13 +1767,23 @@ u32 ExecuteCommand(std::array& dicmd_buf, u32* diimm_buf, u32 address, u else { ret = setsockopt(host_socket, SOL_SOCKET, SO_RCVTIMEO, - reinterpret_cast(&timeout_c), sizeof(int)); + reinterpret_cast(&timeval_c), sizeof(timeval_c)); if (ret < 0) ret = WSAGetLastError(); } - INFO_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: SetTimeOuts( {}({}), {}, {}, {} ):{}", host_socket, - int(guest_socket), timeout_a, timeout_b, timeout_c, ret); + if (ret < 0) + { + ERROR_LOG_FMT(AMMEDIABOARD_NET, + "GC-AM: SetTimeOuts( {}({}), {}, {}, {} ) failed with error {}: {}", + host_socket, int(guest_socket), timeout_a, timeout_b, timeout_c, ret, + Common::DecodeNetworkError(ret)); + } + else + { + INFO_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: SetTimeOuts( {}({}), {}, {}, {} ):{}", + host_socket, int(guest_socket), timeout_a, timeout_b, timeout_c, ret); + } } else {