I've got this new notify code almost working, but...
What exactly is the protocol for locking a table that you intend to
modify? The old notify code just did RelationSetLockForWrite(),
but it's not clear to me that that works correctly --- for one thing,
it doesn't seem to offer any way of detecting failure to acquire the
lock. (RelationSetLockForWrite calls MultiLockReln, which *does*
return a boolean, but RelationSetLockForWrite ignores it...) Also,
it's not at all clear whether I should call RelationUnsetLockForWrite
at the end of the routine or not; some existing code does, some doesn't.
I'm concerned because interlocking of the specialized NOTIFY-related
statements seems to work fine, but they seem not to be interlocked
against user operations on the pg_listener table.
For example, this works as I'd expect:
psql#1 psql#2
begin;
listen z;
notify z;
(hangs up until #1 commits)
end;
because "listen" acquires a write lock on the pg_listener table, which
the notify has to wait for.
But this doesn't work as I'd expect:
psql#1 psql#2
begin;
select * from pg_listener;
notify z;
(completes immediately)
end;
Seems to me the "select" should acquire a read lock that would prevent
the #2 backend from writing pg_listener until the end of #1's transaction.
Is there a bug here, or is there some special definition of user access
to a system table that means the select isn't acquiring a read lock?
Selects and updates on ordinary user tables seem to interlock fine...
regards, tom lane