Skip to content

Commit 3bc68db

Browse files
CuriousGeorgiydrewdzzz
authored andcommitted
client: check ready futures in waitAll and waitCount before waiting
Currently, `waitAll` and `waitCount` unconditionally `wait` instead of checking response readiness. If there are no more responses, it will cause them to hang indefinitely. To fix this, let's check the response readiness first. We should also move the time start to the beginning of the waiting loop, since the initial response checking overhead should not be accounted for the waiting time. Closes #133
1 parent 51e4148 commit 3bc68db

File tree

2 files changed

+35
-5
lines changed

2 files changed

+35
-5
lines changed

src/Client/Connector.hpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -309,16 +309,20 @@ Connector<BUFFER, NetProvider>::waitAll(Connection<BUFFER, NetProvider> &conn,
309309
const std::vector<rid_t> &futures,
310310
int timeout)
311311
{
312+
size_t last_not_ready = 0;
313+
bool finish = false;
314+
if (connectionCheckResponsesReadiness(conn, futures, &last_not_ready, &finish) != 0)
315+
return -1;
316+
if (finish)
317+
return 0;
312318
Timer timer{timeout};
313319
timer.start();
314-
size_t last_not_ready = 0;
315320
while (!conn.hasError()) {
316321
if (m_NetProvider.wait(timer.timeLeft()) != 0) {
317322
conn.setError(std::string("Failed to poll: ") +
318323
strerror(errno), errno);
319324
return -1;
320325
}
321-
bool finish = false;
322326
if (connectionCheckResponsesReadiness(conn, futures, &last_not_ready, &finish) != 0)
323327
return -1;
324328
if (finish)
@@ -361,17 +365,21 @@ int
361365
Connector<BUFFER, NetProvider>::waitCount(Connection<BUFFER, NetProvider> &conn,
362366
size_t future_count, int timeout)
363367
{
364-
Timer timer{timeout};
365-
timer.start();
366368
size_t ready_futures = conn.getFutureCount();
367369
size_t expected_future_count = ready_futures + future_count;
370+
bool finish = false;
371+
if (connectionCheckCountResponsesReadiness(conn, expected_future_count, &finish) != 0)
372+
return -1;
373+
if (finish)
374+
return 0;
375+
Timer timer{timeout};
376+
timer.start();
368377
while (!conn.hasError()) {
369378
if (m_NetProvider.wait(timer.timeLeft()) != 0) {
370379
conn.setError(std::string("Failed to poll: ") +
371380
strerror(errno), errno);
372381
return -1;
373382
}
374-
bool finish = false;
375383
if (connectionCheckCountResponsesReadiness(conn, expected_future_count, &finish) != 0)
376384
return -1;
377385
if (finish)

test/ClientTest.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,6 +1324,28 @@ test_wait(Connector<BUFFER, NetProvider> &client)
13241324
fail_unless(result.header.sync == static_cast<int>(f1));
13251325
fail_unless(result.header.code == 0);
13261326

1327+
TEST_CASE("wait method check future readiness before waiting (gh-133");
1328+
f = conn.ping();
1329+
fail_unless(client.wait(conn, f, WAIT_TIMEOUT) == 0);
1330+
fail_unless(client.wait(conn, f) == 0);
1331+
conn.getResponse(f);
1332+
f = conn.ping();
1333+
fail_unless(client.wait(conn, f, WAIT_TIMEOUT) == 0);
1334+
fail_unless(client.waitAll(conn, {f}) == 0);
1335+
conn.getResponse(f);
1336+
f = conn.ping();
1337+
fail_unless(client.wait(conn, f, WAIT_TIMEOUT) == 0);
1338+
/* FIXME(gh-143): test solely that we check future readiness before waiting. */
1339+
fail_unless(client.waitCount(conn, 0) == 0);
1340+
conn.getResponse(f);
1341+
/* FIXME(gh-132): waitAny does not check connections for ready futures. */
1342+
#if 0
1343+
f = conn.ping();
1344+
fail_unless(client.wait(conn, f, WAIT_TIMEOUT) == 0);
1345+
fail_unless(client.waitAny(conn).has_value());
1346+
conn.getResponse(f);
1347+
#endif
1348+
13271349
client.close(conn);
13281350
}
13291351

0 commit comments

Comments
 (0)