1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-11 20:28:21 +03:00
Making PQrequestCancel safe to call in a signal handler turned out to be
much easier than I feared.  So here are the diffs.

Some notes:
  * I modified the postmaster's packet "iodone" callback interface to allow
    the callback routine to return a continue-or-drop-connection return
    code; this was necessary to allow the connection to be closed after
    receiving a Cancel, rather than proceeding to launch a new backend...
    Being a neatnik, I also made the iodone proc have a typechecked
    parameter list.
  * I deleted all code I could find that had to do with OOB.
  * I made some edits to ensure that all signals mentioned in the code
    are referred to symbolically not by numbers ("SIGUSR2" not "2").
    I think Bruce may have already done at least some of the same edits;
    I hope that merging these patches is not too painful.
This commit is contained in:
Marc G. Fournier
1998-07-09 03:29:11 +00:00
parent 8bf61820f0
commit a0659e3e2c
20 changed files with 597 additions and 287 deletions

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.78 1998/06/27 04:53:43 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.79 1998/07/09 03:28:48 scrappy Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
@ -724,7 +724,7 @@ pg_exec_query_dest(char *query_string, /* string to execute */
/* --------------------------------
* signal handler routines used in PostgresMain()
*
* handle_warn() is used to catch kill(getpid(),1) which
* handle_warn() is used to catch kill(getpid(), SIGHUP) which
* occurs when elog(ERROR) is called.
*
* quickdie() occurs when signalled by the postmaster.
@ -777,7 +777,7 @@ FloatExceptionHandler(SIGNAL_ARGS)
}
/* signal handler for query cancel */
/* signal handler for query cancel signal from postmaster */
static void
QueryCancelHandler(SIGNAL_ARGS)
{
@ -787,12 +787,9 @@ QueryCancelHandler(SIGNAL_ARGS)
void
CancelQuery(void)
{
char dummy;
/* throw it away */
while (pq_recvoob(&dummy, 1) > 0)
;
/* QueryCancel reset in longjump after elog() call */
/* QueryCancel flag will be reset in main loop, which we reach by
* longjmp from elog().
*/
elog(ERROR, "Query was cancelled.");
}
@ -1261,7 +1258,6 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
}
pq_init(Portfd);
whereToSendOutput = Remote;
pq_regoob(QueryCancelHandler); /* we do it here so the backend it connected */
}
else
whereToSendOutput = Debug;
@ -1287,6 +1283,24 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
}
#endif
/* ----------------
* Set up handler for cancel-request signal, and
* send this backend's cancellation info to the frontend.
* This should not be done until we are sure startup is successful.
* ----------------
*/
pqsignal(SIGINT, QueryCancelHandler);
if (whereToSendOutput == Remote &&
PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
{
pq_putnchar("K", 1);
pq_putint((int32) MyProcPid, sizeof(int32));
pq_putint((int32) MyCancelKey, sizeof(int32));
/* Need not flush since ReadyForQuery will do it. */
}
/* ----------------
* if an exception is encountered, processing resumes here
* so we abort the current transaction and start a new one.
@ -1294,7 +1308,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
* so that the slaves signal the master to abort the transaction
* rather than calling AbortCurrentTransaction() themselves.
*
* Note: elog(ERROR) causes a kill(getpid(),1) to occur sending
* Note: elog(ERROR) causes a kill(getpid(), SIGHUP) to occur sending
* us back here.
* ----------------
*/
@ -1325,7 +1339,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
if (!IsUnderPostmaster)
{
puts("\nPOSTGRES backend interactive interface");
puts("$Revision: 1.78 $ $Date: 1998/06/27 04:53:43 $");
puts("$Revision: 1.79 $ $Date: 1998/07/09 03:28:48 $");
}
/* ----------------
@ -1431,7 +1445,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
break;
default:
elog(ERROR, "unknown frontend message was recieved");
elog(ERROR, "unknown frontend message was received");
}
/* ----------------