]> granicus.if.org Git - postgresql/commitdiff
Fix UNLISTEN to fall out quickly if the current backend has never executed
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 13 Feb 2009 17:12:10 +0000 (17:12 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 13 Feb 2009 17:12:10 +0000 (17:12 +0000)
any LISTEN command.  This is more important than it used to be because
DISCARD ALL invokes UNLISTEN.  Connection-pooled applications making heavy
use of DISCARD ALL were seeing significant contention for pg_listener,
as reported by Matteo Beccati.  It seems unlikely that clients using LISTEN
would use pooled connections, so this simple tweak seems sufficient,
especially since the pg_listener implementation is slated to go away soon
anyway.

Back-patch to 8.3, where DISCARD ALL was introduced.

src/backend/commands/async.c

index 06ba738fd47f8cbc7e5df6db2b705ba3f3643b48..38fc57393e66cebd003458b6e90e9a395f2154e4 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.138.2.1 2008/03/12 20:11:54 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.138.2.2 2009/02/13 17:12:10 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -283,6 +283,10 @@ Async_Unlisten(const char *relname)
                if (Trace_notify)
                        elog(DEBUG1, "Async_Unlisten(%s,%d)", relname, MyProcPid);
 
+               /* If we couldn't possibly be listening, no need to queue anything */
+               if (pendingActions == NIL && !unlistenExitRegistered)
+                       return;
+
                queue_listen(LISTEN_UNLISTEN, relname);
        }
 }
@@ -298,6 +302,10 @@ Async_UnlistenAll(void)
        if (Trace_notify)
                elog(DEBUG1, "Async_UnlistenAll(%d)", MyProcPid);
 
+       /* If we couldn't possibly be listening, no need to queue anything */
+       if (pendingActions == NIL && !unlistenExitRegistered)
+               return;
+
        queue_listen(LISTEN_UNLISTEN_ALL, "");
 }