From 01883da47eabc768079559d9109f044940cbe5ee Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Wed, 9 Sep 2020 20:14:13 -0400 Subject: [PATCH] Fix Listener Socket Timeout on Windows (#28) * try checking for timeouts differently on windows * hopefully this test fails on windows * hopefully this test passes on windows * remove debug prints * remove commented otu code --- common/cross_sockets/xsocket.cpp | 9 +++++++++ common/cross_sockets/xsocket.h | 1 + goalc/listener/Listener.cpp | 13 +++++-------- test/test_listener_deci2.cpp | 18 ++++++++++++++++++ 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/common/cross_sockets/xsocket.cpp b/common/cross_sockets/xsocket.cpp index f4c89df7e8..763cf596f4 100644 --- a/common/cross_sockets/xsocket.cpp +++ b/common/cross_sockets/xsocket.cpp @@ -86,3 +86,12 @@ int read_from_socket(int socket, char* buf, int len) { return recv(socket, buf, len, 0); #endif } + +bool socket_timed_out() { +#ifdef __linux + return errno == EAGAIN; +#elif _WIN32 + auto err = WSAGetLastError(); + return err == WSAETIMEDOUT; +#endif +} \ No newline at end of file diff --git a/common/cross_sockets/xsocket.h b/common/cross_sockets/xsocket.h index eb8e09b38c..d0e4bb1c16 100644 --- a/common/cross_sockets/xsocket.h +++ b/common/cross_sockets/xsocket.h @@ -18,3 +18,4 @@ int set_socket_option(int socket, int level, int optname, const void* optval, in int set_socket_timeout(int socket, long microSeconds); int write_to_socket(int socket, const char* buf, int len); int read_from_socket(int socket, char* buf, int len); +bool socket_timed_out(); \ No newline at end of file diff --git a/goalc/listener/Listener.cpp b/goalc/listener/Listener.cpp index 454dcd46f3..1fdb4bbe3d 100644 --- a/goalc/listener/Listener.cpp +++ b/goalc/listener/Listener.cpp @@ -123,7 +123,7 @@ bool Listener::connect_to_target(int n_tries, const std::string& ip, int port) { listen_socket = -1; return false; } else { - printf("[Listener] Socket connected established! (took %d tries)\n", i); + printf("[Listener] Socket connected established! (took %d tries). Waiting for version...\n", i); } // get the GOAL version number, to make sure we connected to the right thing @@ -133,11 +133,8 @@ bool Listener::connect_to_target(int n_tries, const std::string& ip, int port) { bool ok = true; while (prog < 8) { auto r = read_from_socket(listen_socket, (char*)version_buffer + prog, 8 - prog); - if (r < 0) { - ok = false; - break; - } - prog += r; + std::this_thread::sleep_for(std::chrono::microseconds(100000)); + prog += r > 0 ? r : 0; read_tries++; if (read_tries > 50) { ok = false; @@ -181,7 +178,7 @@ void Listener::receive_func() { rcvd += got > 0 ? got : 0; // kick us out if we got a bogus read result - if (got == 0 || (got == -1 && errno != EAGAIN)) { + if (got == 0 || (got == -1 && !socket_timed_out())) { m_connected = false; } @@ -238,7 +235,7 @@ void Listener::receive_func() { got = got > 0 ? got : 0; rcvd += got; msg_prog += got; - if (got == 0 || (got == -1 && errno != EAGAIN)) { + if (got == 0 || (got == -1 && !socket_timed_out())) { m_connected = false; } } diff --git a/test/test_listener_deci2.cpp b/test/test_listener_deci2.cpp index 158a7afb7a..ebc5aedeab 100644 --- a/test/test_listener_deci2.cpp +++ b/test/test_listener_deci2.cpp @@ -45,6 +45,24 @@ TEST(Listener, DeciCheckNoListener) { EXPECT_FALSE(s.check_for_listener()); } +TEST(Listener, CheckConnectionStaysAlive) { + Deci2Server s(always_false); + EXPECT_TRUE(s.init()); + EXPECT_FALSE(s.check_for_listener()); + Listener l; + EXPECT_FALSE(s.check_for_listener()); + bool connected = l.connect_to_target(); + EXPECT_TRUE(connected); + // TODO - some sort of backoff and retry would be better + while (connected && !s.check_for_listener()) { + } + + EXPECT_TRUE(s.check_for_listener()); + std::this_thread::sleep_for(std::chrono::seconds(2)); // sorry for making tests slow. + EXPECT_TRUE(s.check_for_listener()); + EXPECT_TRUE(l.is_connected()); +} + TEST(Listener, DeciThenListener) { for (int i = 0; i < 3; i++) { Deci2Server s(always_false);