77 *
88 *
99 * IDENTIFICATION
10- * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.54 1999/06/10 14:17:09 vadim Exp $
10+ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.55 1999/06/11 09:00:02 vadim Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
@@ -1960,7 +1960,12 @@ UnlockBuffers()
19601960}
19611961if (BufferLocks [i ]& BL_RI_LOCK )
19621962{
1963- Assert (buf -> ri_lock );
1963+ /*
1964+ * Someone else could remove our RI lock when acquiring
1965+ * W lock. This is possible if we came here from elog(ERROR)
1966+ * from IpcSemaphore{Lock|Unlock}(WaitCLSemId). And so we
1967+ * don't do Assert(buf->ri_lock) here.
1968+ */
19641969buf -> ri_lock = false;
19651970}
19661971if (BufferLocks [i ]& BL_W_LOCK )
@@ -2008,7 +2013,6 @@ LockBuffer(Buffer buffer, int mode)
20082013{
20092014Assert (buf -> w_lock );
20102015Assert (buf -> r_locks == 0 );
2011- Assert (!buf -> ri_lock );
20122016Assert (!(BufferLocks [buffer - 1 ]& (BL_R_LOCK |BL_RI_LOCK )))
20132017buf -> w_lock = false;
20142018BufferLocks [buffer - 1 ] &= ~BL_W_LOCK ;
@@ -2043,10 +2047,15 @@ LockBuffer(Buffer buffer, int mode)
20432047Assert (!(BufferLocks [buffer - 1 ]& (BL_R_LOCK |BL_W_LOCK |BL_RI_LOCK )));
20442048while (buf -> r_locks > 0 || buf -> w_lock )
20452049{
2046- if (buf -> r_locks > 3 )
2050+ if (buf -> r_locks > 3 || ( BufferLocks [ buffer - 1 ] & BL_RI_LOCK ) )
20472051{
2048- if (!(BufferLocks [buffer - 1 ]& BL_RI_LOCK ))
2049- BufferLocks [buffer - 1 ] |=BL_RI_LOCK ;
2052+ /*
2053+ * Our RI lock might be removed by concurrent W lock
2054+ * acquiring (see what we do with RI locks below
2055+ * when our own W acquiring succeeded) and so
2056+ * we set RI lock again if we already did this.
2057+ */
2058+ BufferLocks [buffer - 1 ] |=BL_RI_LOCK ;
20502059buf -> ri_lock = true;
20512060}
20522061#ifdef HAS_TEST_AND_SET
@@ -2063,6 +2072,10 @@ LockBuffer(Buffer buffer, int mode)
20632072BufferLocks [buffer - 1 ] |=BL_W_LOCK ;
20642073if (BufferLocks [buffer - 1 ]& BL_RI_LOCK )
20652074{
2075+ /*
2076+ * It's possible to remove RI locks acquired by another
2077+ * W lockers here, but they'll take care about it.
2078+ */
20662079buf -> ri_lock = false;
20672080BufferLocks [buffer - 1 ] &= ~BL_RI_LOCK ;
20682081}