* StartBufferIO: begin I/O on this buffer * (Assumptions) * My process is executing no IO * The buffer is Pinned * * In some scenarios there are race conditions in which multiple backends * could attempt the same I/O operation concurrently. If someone else * has already started I/O on this buffer then we will block on the * I/O condition variable until he's done. * * Input operations ar
| 4673 | * false if someone else already did the work. |
| 4674 | */ |
| 4675 | static bool |
| 4676 | StartBufferIO(BufferDesc *buf, bool forInput) |
| 4677 | { |
| 4678 | uint32 buf_state; |
| 4679 | |
| 4680 | Assert(!InProgressBuf); |
| 4681 | |
| 4682 | for (;;) |
| 4683 | { |
| 4684 | buf_state = LockBufHdr(buf); |
| 4685 | |
| 4686 | if (!(buf_state & BM_IO_IN_PROGRESS)) |
| 4687 | break; |
| 4688 | UnlockBufHdr(buf, buf_state); |
| 4689 | WaitIO(buf); |
| 4690 | } |
| 4691 | |
| 4692 | /* Once we get here, there is definitely no I/O active on this buffer */ |
| 4693 | |
| 4694 | if (forInput ? (buf_state & BM_VALID) : !(buf_state & BM_DIRTY)) |
| 4695 | { |
| 4696 | /* someone else already did the I/O */ |
| 4697 | UnlockBufHdr(buf, buf_state); |
| 4698 | return false; |
| 4699 | } |
| 4700 | |
| 4701 | buf_state |= BM_IO_IN_PROGRESS; |
| 4702 | UnlockBufHdr(buf, buf_state); |
| 4703 | |
| 4704 | #ifdef MPROTECT_BUFFERS |
| 4705 | BufferMProtect(buf, forInput ? PROT_WRITE|PROT_READ : PROT_READ); |
| 4706 | #endif |
| 4707 | |
| 4708 | InProgressBuf = buf; |
| 4709 | IsForInput = forInput; |
| 4710 | |
| 4711 | return true; |
| 4712 | } |
| 4713 | |
| 4714 | /* |
| 4715 | * TerminateBufferIO: release a buffer we were doing I/O on |
no test coverage detected