From a74d8bd8589881e701b2e95b521f1208a9c3c580 Mon Sep 17 00:00:00 2001 From: Andrey Borodin Date: Thu, 10 Oct 2024 10:43:54 +0500 Subject: [PATCH v2] Prevent psql haning in \watch with submillisecond interval --- src/bin/psql/command.c | 11 ++++++++--- src/bin/psql/t/001_basic.pl | 4 ++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 2bb87897505..328d78c73f9 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -5359,6 +5359,10 @@ do_shell(const char *command) * * We break this out of exec_command to avoid having to plaster "volatile" * onto a bunch of exec_command's variables to silence stupider compilers. + * + * "sleep" is the amount of time to sleep during each loop, measured in + * seconds. The internals of this function should use "sleep_ms" for + * precise sleep time calculations. */ static bool do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows) @@ -5484,10 +5488,10 @@ do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows) if (user_title) snprintf(title, title_len, _("%s\t%s (every %gs)\n"), - user_title, timebuf, sleep); + user_title, timebuf, sleep_ms / 1000.0); else snprintf(title, title_len, _("%s (every %gs)\n"), - timebuf, sleep); + timebuf, sleep_ms / 1000.0); myopt.title = title; /* Run the query and print out the result */ @@ -5508,7 +5512,8 @@ do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows) if (pagerpipe && ferror(pagerpipe)) break; - if (sleep == 0) + /* Tight loop, no wait needed */ + if (sleep_ms == 0) continue; #ifdef WIN32 diff --git a/src/bin/psql/t/001_basic.pl b/src/bin/psql/t/001_basic.pl index 5f2f4541af0..dedaf18e44f 100644 --- a/src/bin/psql/t/001_basic.pl +++ b/src/bin/psql/t/001_basic.pl @@ -355,6 +355,10 @@ psql_like( psql_like($node, sprintf('SELECT 1 \watch c=3 i=%g', 0.01), qr/1\n1\n1/, '\watch with 3 iterations'); +# Sub-millisecond wait should not hang +psql_like($node, sprintf('SELECT 1 \watch c=3 i=%g', 0.0001), + qr/1\n1\n1/, '\watch with 3 iterations'); + # Check \watch minimum row count psql_fails_like( $node, -- 2.42.0