Re: Possible race in UnlockBuffers() and UnpinBuffer()

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: "Qingqing Zhou" <zhouqq(at)cs(dot)toronto(dot)edu>
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: Possible race in UnlockBuffers() and UnpinBuffer()
Date: 2006-04-13 16:21:44
Message-ID: 20875.1144945304@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

"Qingqing Zhou" <zhouqq(at)cs(dot)toronto(dot)edu> writes:
> ... 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();

Hmm ... I remember having convinced myself this code was OK, but I guess
I was wrong.

> 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.

No, that would make any attempt to control-C a VACUUM have a significant
probability for panicking the whole database.

I think a better fix might be to arrange for an extra PGSemaphoreUnlock
to not be a problem. This is already true in lwlock.c, and in the
pin-count-waiter too (it'll just cause an extra cycle around the loop).
We'd have to modify ProcSleep to loop until it sees that someone has
actually granted or denied the lock, but that does not seem too hard.
(First thought about it is to change MyProc->waitStatus to have three
states, "waiting/ok/denied".) ProcCancelWaitForSignal could then go
away entirely.

regards, tom lane

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2006-04-13 16:36:25 Re: Practical impediment to supporting multiple SSL libraries
Previous Message Stephen Frost 2006-04-13 16:09:03 Re: Practical impediment to supporting multiple SSL libraries