aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/misc.c
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2008-04-15 13:55:12 +0000
committerBruce Momjian <bruce@momjian.us>2008-04-15 13:55:12 +0000
commit18b286f3e3317c26f27ead1dea8be23c63a7ef2a (patch)
tree380518a08736536d69901e2e9c0a13594a101d63 /src/backend/utils/adt/misc.c
parentfcf053d7829f2d83829256153e856f9a36c83ffd (diff)
downloadpostgresql-18b286f3e3317c26f27ead1dea8be23c63a7ef2a.tar.gz
postgresql-18b286f3e3317c26f27ead1dea8be23c63a7ef2a.zip
Add pg_terminate_backend() to allow terminating only a single session.
Diffstat (limited to 'src/backend/utils/adt/misc.c')
-rw-r--r--src/backend/utils/adt/misc.c63
1 files changed, 49 insertions, 14 deletions
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index f7aaec12f0e..d5e794abee2 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.59 2008/04/04 16:57:21 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.60 2008/04/15 13:55:11 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -27,6 +27,7 @@
#include "postmaster/syslogger.h"
#include "storage/fd.h"
#include "storage/pmsignal.h"
+#include "storage/proc.h"
#include "storage/procarray.h"
#include "utils/builtins.h"
#include "tcop/tcopprot.h"
@@ -89,7 +90,7 @@ current_query(PG_FUNCTION_ARGS)
* Functions to send signals to other backends.
*/
static bool
-pg_signal_backend(int pid, int sig)
+pg_signal_check(int pid)
{
if (!superuser())
ereport(ERROR,
@@ -106,7 +107,16 @@ pg_signal_backend(int pid, int sig)
(errmsg("PID %d is not a PostgreSQL server process", pid)));
return false;
}
+ else
+ return true;
+}
+/*
+ * Functions to send signals to other backends.
+ */
+static bool
+pg_signal_backend(int pid, int sig)
+{
/* If we have setsid(), signal the backend's whole process group */
#ifdef HAVE_SETSID
if (kill(-pid, sig))
@@ -125,7 +135,43 @@ pg_signal_backend(int pid, int sig)
Datum
pg_cancel_backend(PG_FUNCTION_ARGS)
{
- PG_RETURN_BOOL(pg_signal_backend(PG_GETARG_INT32(0), SIGINT));
+ int pid = PG_GETARG_INT32(0);
+
+ if (pg_signal_check(pid))
+ PG_RETURN_BOOL(pg_signal_backend(pid, SIGINT));
+ else
+ PG_RETURN_BOOL(false);
+}
+
+/*
+ * To cleanly terminate a backend, we set PGPROC(pid)->terminate
+ * then send a cancel signal. We get ProcArrayLock only when
+ * setting PGPROC->terminate so the function might fail in
+ * several places, but that is fine because in those cases the
+ * backend is already gone.
+ */
+Datum
+pg_terminate_backend(PG_FUNCTION_ARGS)
+{
+ int pid = PG_GETARG_INT32(0);
+ volatile PGPROC *term_proc;
+
+ /* Is this the super-user, and can we find the PGPROC entry for the pid? */
+ if (pg_signal_check(pid) && (term_proc = BackendPidGetProc(pid)) != NULL)
+ {
+ LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
+ /* Recheck now that we have the ProcArray lock. */
+ if (term_proc->pid == pid)
+ {
+ term_proc->terminate = true;
+ LWLockRelease(ProcArrayLock);
+ PG_RETURN_BOOL(pg_signal_backend(pid, SIGINT));
+ }
+ else
+ LWLockRelease(ProcArrayLock);
+ }
+
+ PG_RETURN_BOOL(false);
}
Datum
@@ -169,17 +215,6 @@ pg_rotate_logfile(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(true);
}
-#ifdef NOT_USED
-
-/* Disabled in 8.0 due to reliability concerns; FIXME someday */
-Datum
-pg_terminate_backend(PG_FUNCTION_ARGS)
-{
- PG_RETURN_INT32(pg_signal_backend(PG_GETARG_INT32(0), SIGTERM));
-}
-#endif
-
-
/* Function to find out which databases make use of a tablespace */
typedef struct