Skip to content

Commit 1316be2

Browse files
committed
Disallow LISTEN in background workers.
It's possible to execute user-defined SQL in some background processes; for example, logical replication workers can fire triggers. This opens the possibility that someone would try to execute LISTEN in such a context. But since only regular backends ever call ProcessNotifyInterrupt, no messages would actually be received, and thus the registered listener would simply prevent the message queue from being cleaned. Eventually NOTIFY would stop working, which is bad. Perhaps someday somebody will invent infrastructure to make listening in a background worker actually useful. In the meantime, forbid it. Back-patch to v13, which is where we introduced the MyBackendType variable. It'd be a lot harder to implement the check without that, and it doesn't seem worth the trouble. Discussion: https://postgr.es/m/153243441449.1404.2274116228506175596@wrigleys.postgresql.org
1 parent e581360 commit 1316be2

File tree

1 file changed

+17
-0
lines changed

1 file changed

+17
-0
lines changed

src/backend/tcop/utility.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,23 @@ standard_ProcessUtility(PlannedStmt *pstmt,
803803
ListenStmt *stmt = (ListenStmt *) parsetree;
804804

805805
CheckRestrictedOperation("LISTEN");
806+
807+
/*
808+
* We don't allow LISTEN in background processes, as there is
809+
* no mechanism for them to collect NOTIFY messages, so they'd
810+
* just block cleanout of the async SLRU indefinitely.
811+
* (Authors of custom background workers could bypass this
812+
* restriction by calling Async_Listen directly, but then it's
813+
* on them to provide some mechanism to process the message
814+
* queue.) Note there seems no reason to forbid UNLISTEN.
815+
*/
816+
if (MyBackendType != B_BACKEND)
817+
ereport(ERROR,
818+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
819+
/* translator: %s is name of a SQL command, eg LISTEN */
820+
errmsg("cannot execute %s within a background process",
821+
"LISTEN")));
822+
806823
Async_Listen(stmt->conditionname);
807824
}
808825
break;

0 commit comments

Comments
 (0)