Possible race in UnlockBuffers() and UnpinBuffer()

From: "Qingqing Zhou" <zhouqq(at)cs(dot)toronto(dot)edu>
To: pgsql-hackers(at)postgresql(dot)org
Subject: Possible race in UnlockBuffers() and UnpinBuffer()
Date: 2006-04-13 08:10:52
Message-ID: e1l18q$2nba$1@news.hub.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: 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 by UnpinBuffer() */
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

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Martijn van Oosterhout 2006-04-13 08:15:16 Re: Practical impediment to supporting multiple SSL libraries
Previous Message Dave Page 2006-04-13 07:48:54 Re: Practical impediment to supporting multiple SSL libraries