]> granicus.if.org Git - postgresql/commitdiff
Removed bad Assert(!buf->ri_lock) when unlocking exclusively
authorVadim B. Mikheev <vadim4o@yahoo.com>
Fri, 11 Jun 1999 09:00:02 +0000 (09:00 +0000)
committerVadim B. Mikheev <vadim4o@yahoo.com>
Fri, 11 Jun 1999 09:00:02 +0000 (09:00 +0000)
locked buffer.

src/backend/storage/buffer/bufmgr.c

index f0b397dbea447719258f7aa0927ffb0d22d45a7d..446917a4c5008d96d34f4cabc17b6dde2d627ccc 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.54 1999/06/10 14:17:09 vadim Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.55 1999/06/11 09:00:02 vadim Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1960,7 +1960,12 @@ UnlockBuffers()
                }
                if (BufferLocks[i] & BL_RI_LOCK)
                {
-                       Assert(buf->ri_lock);
+                       /* 
+                        * Someone else could remove our RI lock when acquiring
+                        * W lock. This is possible if we came here from elog(ERROR)
+                        * from IpcSemaphore{Lock|Unlock}(WaitCLSemId). And so we
+                        * don't do Assert(buf->ri_lock) here.
+                        */
                        buf->ri_lock = false;
                }
                if (BufferLocks[i] & BL_W_LOCK)
@@ -2008,7 +2013,6 @@ LockBuffer(Buffer buffer, int mode)
                {
                        Assert(buf->w_lock);
                        Assert(buf->r_locks == 0);
-                       Assert(!buf->ri_lock);
                        Assert(!(BufferLocks[buffer - 1] & (BL_R_LOCK | BL_RI_LOCK)))
                                buf->w_lock = false;
                        BufferLocks[buffer - 1] &= ~BL_W_LOCK;
@@ -2043,10 +2047,15 @@ LockBuffer(Buffer buffer, int mode)
                Assert(!(BufferLocks[buffer - 1] & (BL_R_LOCK | BL_W_LOCK | BL_RI_LOCK)));
                while (buf->r_locks > 0 || buf->w_lock)
                {
-                       if (buf->r_locks > 3)
+                       if (buf->r_locks > 3 || (BufferLocks[buffer - 1] & BL_RI_LOCK))
                        {
-                               if (!(BufferLocks[buffer - 1] & BL_RI_LOCK))
-                                       BufferLocks[buffer - 1] |= BL_RI_LOCK;
+                               /*
+                                * Our RI lock might be removed by concurrent W lock
+                                * acquiring (see what we do with RI locks below
+                                * when our own W acquiring succeeded) and so
+                                * we set RI lock again if we already did this.
+                                */
+                               BufferLocks[buffer - 1] |= BL_RI_LOCK;
                                buf->ri_lock = true;
                        }
 #ifdef HAS_TEST_AND_SET
@@ -2063,6 +2072,10 @@ LockBuffer(Buffer buffer, int mode)
                BufferLocks[buffer - 1] |= BL_W_LOCK;
                if (BufferLocks[buffer - 1] & BL_RI_LOCK)
                {
+                       /*
+                        * It's possible to remove RI locks acquired by another
+                        * W lockers here, but they'll take care about it.
+                        */
                        buf->ri_lock = false;
                        BufferLocks[buffer - 1] &= ~BL_RI_LOCK;
                }