Skip to content

Commit 75e5c49

Browse files
client: check wait return code in waitAny
Currently, we do not check the return code of `wait` in `waitAny`. If there is an error, we must log it and return a `nullopt`. Closes #121
1 parent f964491 commit 75e5c49

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

src/Client/Connector.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,10 @@ Connector<BUFFER, NetProvider>::waitAny(int timeout)
301301
Timer timer{timeout};
302302
timer.start();
303303
while (m_ReadyToDecode.empty()) {
304-
m_NetProvider.wait(timer.timeLeft());
304+
if (m_NetProvider.wait(timer.timeLeft()) != 0) {
305+
LOG_ERROR("Failed to poll connections: ", strerror(errno));
306+
return std::nullopt;
307+
}
305308
if (timer.isExpired())
306309
break;
307310
}

test/ClientTest.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@
3232
#include "Utils/System.hpp"
3333
#include "Utils/UserTuple.hpp"
3434

35-
#include "../src/Client/LibevNetProvider.hpp"
3635
#include "../src/Client/Connector.hpp"
36+
#include "../src/Client/LibevNetProvider.hpp"
37+
38+
#include <thread>
3739

3840
const char *localhost = "127.0.0.1";
3941
int port = 3301;
@@ -1144,6 +1146,11 @@ response_decoding(Connector<BUFFER, NetProvider> &client)
11441146
client.close(conn);
11451147
}
11461148

1149+
void sigusr_handler(int signo)
1150+
{
1151+
fail_unless(signo != SIGINT);
1152+
}
1153+
11471154
/** Checks all available `wait` methods of connector. */
11481155
template <class BUFFER, class NetProvider>
11491156
void
@@ -1324,6 +1331,30 @@ test_wait(Connector<BUFFER, NetProvider> &client)
13241331
fail_unless(result.header.sync == static_cast<int>(f1));
13251332
fail_unless(result.header.code == 0);
13261333

1334+
#ifdef __linux__
1335+
TEST_CASE("waitAny internal wait failure (gh-121)");
1336+
static constexpr double LONG_SLEEP_TIME = 2;
1337+
f = conn.call("remote_sleep", std::forward_as_tuple(LONG_SLEEP_TIME));
1338+
fail_unless(!conn.futureIsReady(f));
1339+
pthread_t tid = pthread_self();
1340+
struct sigaction act;
1341+
act.sa_handler = sigusr_handler;
1342+
act.sa_flags = 0;
1343+
sigemptyset(&act.sa_mask);
1344+
sigaction(SIGUSR1, &act, nullptr);
1345+
auto &&signal_thread = std::thread([tid] {
1346+
sleep(LONG_SLEEP_TIME / 2);
1347+
pthread_kill(tid, SIGUSR1);
1348+
});
1349+
fail_unless(!client.waitAny().has_value());
1350+
fail_unless(client.waitAny().has_value());
1351+
fail_unless(conn.futureIsReady(f));
1352+
response = conn.getResponse(f);
1353+
fail_unless(response.has_value());
1354+
signal_thread.join();
1355+
sigaction(SIGUSR1, nullptr, nullptr);
1356+
#endif /* __linux__ */
1357+
13271358
client.close(conn);
13281359
}
13291360

0 commit comments

Comments
 (0)