From: Andres Freund Date: Tue, 28 Jan 2014 17:51:33 +0000 (+0100) Subject: Don't let ReplicationSlotAcquire succeed in the midst of ReplicationSlotCreate. X-Git-Url: http://waps.l3s.uni-hannover.de/gitweb/?a=commitdiff_plain;h=7d97b442a2a49532f4eccf4098179756eab476be;p=users%2Frhaas%2Fpostgres.git Don't let ReplicationSlotAcquire succeed in the midst of ReplicationSlotCreate. --- 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); } /*