Possible race in UnlockBuffers() and UnpinBuffer() - Mailing list pgsql-hackers

From Qingqing Zhou
Subject Possible race in UnlockBuffers() and UnpinBuffer()
Date
Msg-id e1l18q$2nba$1@news.hub.org
Whole thread Raw
Responses Re: Possible race in UnlockBuffers() and UnpinBuffer()
List pgsql-hackers
We have a wait-pin-to-1 mechanism in LockBufferForCleanup() like this:
   1:  bufHdr->wait_backend_pid = MyProcPid;   2:  bufHdr->flags |= BM_PIN_COUNT_WAITER;   3:  PinCountWaitBuf =
bufHdr;  4:  UnlockBufHdr_NoHoldoff(bufHdr);   5:  LockBuffer(buffer, BUFFER_LOCK_UNLOCK);   6:  /* Wait to be signaled
byUnpinBuffer() */   7:  ProcWaitForSignal();
 

Say if the waiter encounters an error on line 5 or gets a cancel signal on
line 6, it will abort current transaction and call UnlockBuffers() to cancel
the wait. However, a possible execution sequence involving another process
doing UnpinBuffer() may look like this:

unpinner: lockHdr(); read and reset flag; unlockHdr();
waiter:  lockHdr(); reset flag; unlockHdr(); ProcCancelWaitForSignal();
unpinner: ProcSendSignal();

After this, the proc->sem will be bumped to 1 unexpectedly ... Since this
problem is rare, a possible fix is to put a critical section around line 1
to 7 and remove UnlockBuffers() accordingly.

Regards,
Qingqing










pgsql-hackers by date:

Previous
From: "Dave Page"
Date:
Subject: Re: Practical impediment to supporting multiple SSL libraries
Next
From: Martijn van Oosterhout
Date:
Subject: Re: Practical impediment to supporting multiple SSL libraries