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

Commitcafe105

Browse files
committed
Allow SIGINT to cancel psql database reconnections.
After installing the SIGINT handler in psql, SIGINT can no longer canceldatabase reconnections. For instance, if the user starts a reconnectionand then needs to do some form of interaction (ie psql is polling),there is no way to cancel the reconnection process currently.Use PQconnectStartParams() in order to insert a cancel_pressed checkinto the polling loop.Tristan Partin, reviewed by Gurjeet Singh, Heikki Linnakangas, JelteFennema-Nio, and me.Discussion:http://postgr.es/m/D08WWCPVHKHN.3QELIKZJ2D9RZ@neon.tech
1 parentf5e4ded commitcafe105

File tree

1 file changed

+71
-1
lines changed

1 file changed

+71
-1
lines changed

‎src/bin/psql/command.c

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ static void discard_query_text(PsqlScanState scan_state, ConditionalStack cstack
159159
staticboolcopy_previous_query(PQExpBufferquery_buf,PQExpBufferprevious_buf);
160160
staticbooldo_connect(enumtrivaluereuse_previous_specification,
161161
char*dbname,char*user,char*host,char*port);
162+
staticvoidwait_until_connected(PGconn*conn);
162163
staticbooldo_edit(constchar*filename_arg,PQExpBufferquery_buf,
163164
intlineno,booldiscard_on_quit,bool*edited);
164165
staticbooldo_shell(constchar*command);
@@ -3595,11 +3596,12 @@ do_connect(enum trivalue reuse_previous_specification,
35953596
values[paramnum]=NULL;
35963597

35973598
/* Note we do not want libpq to re-expand the dbname parameter */
3598-
n_conn=PQconnectdbParams(keywords,values, false);
3599+
n_conn=PQconnectStartParams(keywords,values, false);
35993600

36003601
pg_free(keywords);
36013602
pg_free(values);
36023603

3604+
wait_until_connected(n_conn);
36033605
if (PQstatus(n_conn)==CONNECTION_OK)
36043606
break;
36053607

@@ -3748,6 +3750,74 @@ do_connect(enum trivalue reuse_previous_specification,
37483750
return true;
37493751
}
37503752

3753+
/*
3754+
* Processes the connection sequence described by PQconnectStartParams(). Don't
3755+
* worry about reporting errors in this function. Our caller will check the
3756+
* connection's status, and report appropriately.
3757+
*/
3758+
staticvoid
3759+
wait_until_connected(PGconn*conn)
3760+
{
3761+
boolforRead= false;
3762+
3763+
while (true)
3764+
{
3765+
intrc;
3766+
intsock;
3767+
time_tend_time;
3768+
3769+
/*
3770+
* On every iteration of the connection sequence, let's check if the
3771+
* user has requested a cancellation.
3772+
*/
3773+
if (cancel_pressed)
3774+
break;
3775+
3776+
/*
3777+
* Do not assume that the socket remains the same across
3778+
* PQconnectPoll() calls.
3779+
*/
3780+
sock=PQsocket(conn);
3781+
if (sock==-1)
3782+
break;
3783+
3784+
/*
3785+
* If the user sends SIGINT between the cancel_pressed check, and
3786+
* polling of the socket, it will not be recognized. Instead, we will
3787+
* just wait until the next step in the connection sequence or forever,
3788+
* which might require users to send SIGTERM or SIGQUIT.
3789+
*
3790+
* Some solutions would include the "self-pipe trick," using
3791+
* pselect(2) and ppoll(2), or using a timeout.
3792+
*
3793+
* The self-pipe trick requires a bit of code to setup. pselect(2) and
3794+
* ppoll(2) are not on all the platforms we support. The simplest
3795+
* solution happens to just be adding a timeout, so let's wait for 1
3796+
* second and check cancel_pressed again.
3797+
*/
3798+
end_time=time(NULL)+1;
3799+
rc=PQsocketPoll(sock,forRead, !forRead,end_time);
3800+
if (rc==-1)
3801+
return;
3802+
3803+
switch (PQconnectPoll(conn))
3804+
{
3805+
casePGRES_POLLING_OK:
3806+
casePGRES_POLLING_FAILED:
3807+
return;
3808+
casePGRES_POLLING_READING:
3809+
forRead= true;
3810+
continue;
3811+
casePGRES_POLLING_WRITING:
3812+
forRead= false;
3813+
continue;
3814+
casePGRES_POLLING_ACTIVE:
3815+
pg_unreachable();
3816+
}
3817+
}
3818+
3819+
pg_unreachable();
3820+
}
37513821

37523822
void
37533823
connection_warnings(boolin_startup)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp