From 7d97b442a2a49532f4eccf4098179756eab476be Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Tue, 28 Jan 2014 18:51:33 +0100 Subject: [PATCH] Don't let ReplicationSlotAcquire succeed in the midst of ReplicationSlotCreate. --- src/backend/replication/slot.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c index f3894f1502..cc376b8b0a 100644 --- a/src/backend/replication/slot.c +++ b/src/backend/replication/slot.c @@ -261,27 +261,32 @@ ReplicationSlotCreate(const char *name, bool db_specific) /* * We need to briefly prevent any other backend from iterating over the - * slots while we flip the in_use flag. + * slots while we flip the in_use flag. We also need to set the active + * flag while holding the ControlLock as otherwise a concurrent + * SlotAcquire() could acquire the slot as well. */ LWLockAcquire(ReplicationSlotControlLock, LW_EXCLUSIVE); - slot->in_use = true; - LWLockRelease(ReplicationSlotControlLock); - /* - * Now that the slot has been marked as in_use, it's safe to let somebody - * else try to allocate a slot. - */ - LWLockRelease(ReplicationSlotAllocationLock); + slot->in_use = true; /* We can now mark the slot active, and that makes it our slot. */ { volatile ReplicationSlot *vslot = slot; SpinLockAcquire(&slot->mutex); + Assert(!vslot->active); vslot->active = true; SpinLockRelease(&slot->mutex); MyReplicationSlot = slot; } + + LWLockRelease(ReplicationSlotControlLock); + + /* + * Now that the slot has been marked as in_use and in_active, it's safe to + * let somebody else try to allocate a slot. + */ + LWLockRelease(ReplicationSlotAllocationLock); } /* -- 2.39.5