/*
* 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);
}
/*