diff options
Diffstat (limited to 'contrib/miscutil/misc_utils.c')
-rw-r--r-- | contrib/miscutil/misc_utils.c | 83 |
1 files changed, 76 insertions, 7 deletions
diff --git a/contrib/miscutil/misc_utils.c b/contrib/miscutil/misc_utils.c index 24d069f71c2..75184439717 100644 --- a/contrib/miscutil/misc_utils.c +++ b/contrib/miscutil/misc_utils.c @@ -10,12 +10,27 @@ */ #include <unistd.h> +#include <signal.h> +#include <string.h> +#include <errno.h> #include "postgres.h" +#include "access/heapam.h" +#include "access/htup.h" +#include "access/relscan.h" +#include "access/skey.h" +#include "access/tupdesc.h" +#include "catalog/catname.h" +#include "catalog/pg_listener.h" +#include "storage/lmgr.h" +#include "utils/fmgr.h" #include "utils/palloc.h" +#include "utils/rel.h" +#include "utils/tqual.h" #include "misc_utils.h" -#include "assert_test.h" + +#define MIN(x,y) ((x)<=(y) ? (x) : (y)) extern int ExecutorLimit(int limit); extern void Async_Unlisten(char *relname, int pid); @@ -23,7 +38,6 @@ extern int assertTest(int val); #ifdef ASSERT_CHECKING_TEST extern int assertEnable(int val); - #endif int @@ -57,6 +71,62 @@ min(int x, int y) return ((x < y) ? x : y); } +/* + * Return the number of active listeners on a relation name. + */ +int +active_listeners(text *relname) +{ + HeapTuple lTuple; + Relation lRel; + HeapScanDesc sRel; + TupleDesc tdesc; + ScanKeyData key; + Datum d; + bool isnull; + int len, pid; + int count = 0; + int ourpid = getpid(); + char listen_name[NAMEDATALEN]; + + lRel = heap_openr(ListenerRelationName); + tdesc = RelationGetDescr(lRel); + LockRelation(lRel, AccessShareLock); + + if (relname && (VARSIZE(relname) > VARHDRSZ)) { + len = MIN(VARSIZE(relname)-VARHDRSZ, NAMEDATALEN-1); + strncpy(listen_name, VARDATA(relname), len); + listen_name[len] = '\0'; + ScanKeyEntryInitialize(&key, 0, + Anum_pg_listener_relname, + F_NAMEEQ, + PointerGetDatum(listen_name)); + sRel = heap_beginscan(lRel, 0, SnapshotNow, 1, &key); + } else { + sRel = heap_beginscan(lRel, 0, SnapshotNow, 0, (ScanKey)NULL); + } + + while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0))) + { + d = heap_getattr(lTuple, Anum_pg_listener_pid, tdesc, &isnull); + pid = DatumGetInt32(d); +#ifdef HAVE_KILL + if ((pid == ourpid) || (kill(pid, SIGTSTP) == 0)) { + /* elog(NOTICE, "%d ok", pid); */ + count++; + } +#else + count++; +#endif + } + heap_endscan(sRel); + + UnlockRelation(lRel, AccessShareLock); + heap_close(lRel); + + return count; +} + int assert_enable(int val) { @@ -69,15 +139,14 @@ assert_test(int val) { return assertTest(val); } - #endif /* end of file */ /* - * Local variables: - * tab-width: 4 - * c-indent-level: 4 - * c-basic-offset: 4 + * Local Variables: + * tab-width: 4 + * c-indent-level: 4 + * c-basic-offset: 4 * End: */ |