Skip to content

Commit f07a20c

Browse files
committed
Improve WIN32 waiting logic in psql's \watch command.
do_watch had some leftover logic for enabling siglongjmp out of waiting for input. That's never done anything on Windows (cf. psql_cancel_callback), and do_watch no longer relies on it for non-Windows, so let's drop it. Also, when the user cancels \watch by pressing ^C, the Windows code would run the query one more time before exiting. That doesn't seem very desirable, and it's not what happens on other platforms. Use the "done" flag similarly to non-Windows to avoid the extra query execution. Yugo Nagata (with minor fixes by me) Discussion: https://postgr.es/m/20240305220552.85fd4afd6b6b8103bf4fe3d0@sraoss.co.jp
1 parent 270af6f commit f07a20c

File tree

1 file changed

+10
-17
lines changed

1 file changed

+10
-17
lines changed

src/bin/psql/command.c

+10-17
Original file line numberDiff line numberDiff line change
@@ -5173,12 +5173,12 @@ do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows)
51735173
FILE *pagerpipe = NULL;
51745174
int title_len;
51755175
int res = 0;
5176+
bool done = false;
51765177
#ifndef WIN32
51775178
sigset_t sigalrm_sigchld_sigint;
51785179
sigset_t sigalrm_sigchld;
51795180
sigset_t sigint;
51805181
struct itimerval interval;
5181-
bool done = false;
51825182
#endif
51835183

51845184
if (!query_buf || query_buf->len <= 0)
@@ -5260,7 +5260,6 @@ do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows)
52605260
if (!pagerpipe)
52615261
myopt.topt.pager = 0;
52625262

5263-
52645263
/*
52655264
* If there's a title in the user configuration, make sure we have room
52665265
* for it in the title buffer. Allow 128 bytes for the timestamp plus 128
@@ -5270,7 +5269,8 @@ do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows)
52705269
title_len = (user_title ? strlen(user_title) : 0) + 256;
52715270
title = pg_malloc(title_len);
52725271

5273-
for (;;)
5272+
/* Loop to run query and then sleep awhile */
5273+
while (!done)
52745274
{
52755275
time_t timer;
52765276
char timebuf[128];
@@ -5305,6 +5305,7 @@ do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows)
53055305
if (iter && (--iter <= 0))
53065306
break;
53075307

5308+
/* Quit if error on pager pipe (probably pager has quit) */
53085309
if (pagerpipe && ferror(pagerpipe))
53095310
break;
53105311

@@ -5314,28 +5315,22 @@ do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows)
53145315
#ifdef WIN32
53155316

53165317
/*
5317-
* Set up cancellation of 'watch' via SIGINT. We redo this each time
5318-
* through the loop since it's conceivable something inside
5319-
* PSQLexecWatch could change sigint_interrupt_jmp.
5318+
* Wait a while before running the query again. Break the sleep into
5319+
* short intervals (at most 1s); that's probably unnecessary since
5320+
* pg_usleep is interruptible on Windows, but it's cheap insurance.
53205321
*/
5321-
if (sigsetjmp(sigint_interrupt_jmp, 1) != 0)
5322-
break;
5323-
5324-
/*
5325-
* Enable 'watch' cancellations and wait a while before running the
5326-
* query again. Break the sleep into short intervals (at most 1s).
5327-
*/
5328-
sigint_interrupt_enabled = true;
53295322
for (long i = sleep_ms; i > 0;)
53305323
{
53315324
long s = Min(i, 1000L);
53325325

53335326
pg_usleep(s * 1000L);
53345327
if (cancel_pressed)
5328+
{
5329+
done = true;
53355330
break;
5331+
}
53365332
i -= s;
53375333
}
5338-
sigint_interrupt_enabled = false;
53395334
#else
53405335
/* sigwait() will handle SIGINT. */
53415336
sigprocmask(SIG_BLOCK, &sigint, NULL);
@@ -5369,8 +5364,6 @@ do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows)
53695364

53705365
/* Unblock SIGINT so that slow queries can be interrupted. */
53715366
sigprocmask(SIG_UNBLOCK, &sigint, NULL);
5372-
if (done)
5373-
break;
53745367
#endif
53755368
}
53765369

0 commit comments

Comments
 (0)