It sorta works, but I'm confused about locking

Tom Lane <tgl@sss.pgh.pa.us>

From: Tom Lane <tgl@sss.pgh.pa.us>
To: pgsql-hackers@postgreSQL.org
Date: 1998-09-27T21:34:33Z
Lists: pgsql-hackers
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