Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5d43c3c

Browse files
committed
Fix query cancellation handling in psql
The refactoring done ina4fd3aa for query cancellation has messed upwith the logic in psql by mixing CancelRequested and cancel_pressed,breaking for example \watch. The former would be switched to true if acancellation request has been attempted and that it actually succeeded,and the latter tracks if a cancellation attempt has been done.This commit brings back the code of psql to a state consistent to whatit was beforea4fd3aa, without giving up on the refactoring piecesintroduced. It should be actually possible to merge more both flags astheir concepts are close enough, however note that psql's --single-stepmode relies on cancel_pressed to be always set, so this requires morecareful analysis left for later.While on it, fix the declarations of CancelRequested (in cancel.c) andcancel_pressed (in psql) to be volatile sig_atomic_t. Previously,both were declared as booleans, which should be fine on modernplatforms, but the C standard recommends the use of sig_atomic_t forvariables used in signal handlers. Note that since its introduction ina179232, CancelRequested declaration was not volatile.Reported-by: Jeff JanesAuthor: Michael PaquierDiscussion:https://postgr.es/m/CAMkU=1zpoUDGKqWKuMWkj7t-bOCaJDx0r=5te_-d0B2HVLABXg@mail.gmail.com
1 parentb925a00 commit5d43c3c

File tree

5 files changed

+29
-25
lines changed

5 files changed

+29
-25
lines changed

‎src/bin/psql/common.c

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ NoticeProcessor(void *arg, const char *message)
233233
*
234234
* SIGINT is supposed to abort all long-running psql operations, not only
235235
* database queries. In most places, this is accomplished by checking
236-
*CancelRequested during long-running loops. However, that won't work when
236+
*cancel_pressed during long-running loops. However, that won't work when
237237
* blocked on user input (in readline() or fgets()). In those places, we
238238
* set sigint_interrupt_enabled true while blocked, instructing the signal
239239
* catcher to longjmp through sigint_interrupt_jmp. We assume readline and
@@ -246,32 +246,22 @@ volatile bool sigint_interrupt_enabled = false;
246246

247247
sigjmp_bufsigint_interrupt_jmp;
248248

249-
#ifndefWIN32
250-
251249
staticvoid
252250
psql_cancel_callback(void)
253251
{
252+
#ifndefWIN32
254253
/* if we are waiting for input, longjmp out of it */
255254
if (sigint_interrupt_enabled)
256255
{
257256
sigint_interrupt_enabled= false;
258257
siglongjmp(sigint_interrupt_jmp,1);
259258
}
259+
#endif
260260

261261
/* else, set cancel flag to stop any long-running loops */
262-
CancelRequested= true;
263-
}
264-
265-
#else
266-
267-
staticvoid
268-
psql_cancel_callback(void)
269-
{
270-
/* nothing to do here */
262+
cancel_pressed= true;
271263
}
272264

273-
#endif/* !WIN32 */
274-
275265
void
276266
psql_setup_cancel_handler(void)
277267
{
@@ -638,7 +628,7 @@ PSQLexecWatch(const char *query, const printQueryOpt *opt)
638628
* consumed. The user's intention, though, is to cancel the entire watch
639629
* process, so detect a sent cancellation request and exit in this case.
640630
*/
641-
if (CancelRequested)
631+
if (cancel_pressed)
642632
{
643633
PQclear(res);
644634
return0;
@@ -838,8 +828,8 @@ ExecQueryTuples(const PGresult *result)
838828
{
839829
constchar*query=PQgetvalue(result,r,c);
840830

841-
/* Abandon execution ifCancelRequested */
842-
if (CancelRequested)
831+
/* Abandon execution ifcancel_pressed */
832+
if (cancel_pressed)
843833
gotoloop_exit;
844834

845835
/*
@@ -1207,7 +1197,7 @@ SendQuery(const char *query)
12071197
if (fgets(buf,sizeof(buf),stdin)!=NULL)
12081198
if (buf[0]=='x')
12091199
gotosendquery_cleanup;
1210-
if (CancelRequested)
1200+
if (cancel_pressed)
12111201
gotosendquery_cleanup;
12121202
}
12131203
elseif (pset.echo==PSQL_ECHO_QUERIES)
@@ -1751,7 +1741,7 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec)
17511741
* writing things to the stream, we presume $PAGER has disappeared and
17521742
* stop bothering to pull down more data.
17531743
*/
1754-
if (ntuples<fetch_count||CancelRequested||flush_error||
1744+
if (ntuples<fetch_count||cancel_pressed||flush_error||
17551745
ferror(fout))
17561746
break;
17571747
}

‎src/fe_utils/cancel.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
#include"postgres_fe.h"
1818

19-
#include<signal.h>
2019
#include<unistd.h>
2120

2221
#include"fe_utils/cancel.h"
@@ -37,8 +36,20 @@
3736
(void) rc_; \
3837
} while (0)
3938

39+
/*
40+
* Contains all the information needed to cancel a query issued from
41+
* a database connection to the backend.
42+
*/
4043
staticPGcancel*volatilecancelConn=NULL;
41-
boolCancelRequested= false;
44+
45+
/*
46+
* CancelRequested tracks if a cancellation request has completed after
47+
* a signal interruption. Note that if cancelConn is not set, in short
48+
* if SetCancelConn() was never called or if ResetCancelConn() freed
49+
* the cancellation object, then CancelRequested is switched to true after
50+
* all cancellation attempts.
51+
*/
52+
volatilesig_atomic_tCancelRequested= false;
4253

4354
#ifdefWIN32
4455
staticCRITICAL_SECTIONcancelConnLock;

‎src/fe_utils/print.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
#include<limits.h>
2121
#include<math.h>
22-
#include<signal.h>
2322
#include<unistd.h>
2423

2524
#ifndefWIN32
@@ -41,7 +40,7 @@
4140
* Note: print.c's general strategy for when to check cancel_pressed is to do
4241
* so at completion of each row of output.
4342
*/
44-
volatileboolcancel_pressed= false;
43+
volatilesig_atomic_tcancel_pressed= false;
4544

4645
staticboolalways_ignore_sigpipe= false;
4746

‎src/include/fe_utils/cancel.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
#ifndefCANCEL_H
1515
#defineCANCEL_H
1616

17+
#include<signal.h>
18+
1719
#include"libpq-fe.h"
1820

19-
externboolCancelRequested;
21+
externvolatilesig_atomic_tCancelRequested;
2022

2123
externvoidSetCancelConn(PGconn*conn);
2224
externvoidResetCancelConn(void);

‎src/include/fe_utils/print.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#ifndefPRINT_H
1414
#definePRINT_H
1515

16+
#include<signal.h>
17+
1618
#include"libpq-fe.h"
1719

1820

@@ -175,7 +177,7 @@ typedef struct printQueryOpt
175177
}printQueryOpt;
176178

177179

178-
externvolatileboolcancel_pressed;
180+
externvolatilesig_atomic_tcancel_pressed;
179181

180182
externconstprintTextFormatpg_asciiformat;
181183
externconstprintTextFormatpg_asciiformat_old;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp