Skip to content

Commit f523d2c

Browse files
committed
don't forget to unlock current slot too
1 parent 788d41c commit f523d2c

File tree

1 file changed

+17
-6
lines changed

1 file changed

+17
-6
lines changed

src/pathman_workers.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -584,12 +584,14 @@ partition_table_concurrently(PG_FUNCTION_ARGS)
584584
#define tostr(str) ( #str ) /* convert function's name to literal */
585585

586586
Oid relid = PG_GETARG_OID(0);
587-
int empty_slot_idx = -1;
587+
int empty_slot_idx = -1; /* do we have a slot for BGWorker? */
588588
int i;
589589

590590
/* Check if relation is a partitioned table */
591591
shout_if_prel_is_invalid(relid,
592+
/* We also lock the parent relation */
592593
get_pathman_relation_info_after_lock(relid, true),
594+
/* Partitioning type does not matter here */
593595
PT_INDIFFERENT);
594596

595597
/*
@@ -601,30 +603,38 @@ partition_table_concurrently(PG_FUNCTION_ARGS)
601603
ConcurrentPartSlot *cur_slot = &concurrent_part_slots[i];
602604
bool keep_this_lock = false;
603605

606+
/* Lock current slot */
604607
SpinLockAcquire(&cur_slot->mutex);
605608

606-
/* Should we take this slot into account? */
609+
/* Should we take this slot into account? (it should be FREE) */
607610
if (empty_slot_idx < 0 && cur_slot->worker_status == CPS_FREE)
608611
{
609-
empty_slot_idx = i;
610-
keep_this_lock = true;
612+
empty_slot_idx = i; /* yes, remember this slot */
613+
keep_this_lock = true; /* also don't unlock it */
611614
}
612615

616+
/* Oops, looks like we already have BGWorker for this table */
613617
if (cur_slot->relid == relid &&
614618
cur_slot->dbid == MyDatabaseId)
615619
{
616-
if (empty_slot_idx >= 0)
617-
SpinLockRelease(&cur_slot->mutex);
620+
/* Unlock current slot */
621+
SpinLockRelease(&cur_slot->mutex);
622+
623+
/* Release borrowed slot for new BGWorker too */
624+
if (empty_slot_idx >= 0 && empty_slot_idx != i)
625+
SpinLockRelease(&concurrent_part_slots[empty_slot_idx].mutex);
618626

619627
elog(ERROR,
620628
"Table \"%s\" is already being partitioned",
621629
get_rel_name(relid));
622630
}
623631

632+
/* Normally we don't want to keep it */
624633
if (!keep_this_lock)
625634
SpinLockRelease(&cur_slot->mutex);
626635
}
627636

637+
/* Looks like we could not find an empty slot */
628638
if (empty_slot_idx < 0)
629639
elog(ERROR, "No empty worker slots found");
630640
else
@@ -634,6 +644,7 @@ partition_table_concurrently(PG_FUNCTION_ARGS)
634644
GetAuthenticatedUserId(), CPS_WORKING,
635645
MyDatabaseId, relid, 1000, 1.0);
636646

647+
/* Now we can safely unlock slot for new BGWorker */
637648
SpinLockRelease(&concurrent_part_slots[empty_slot_idx].mutex);
638649
}
639650

0 commit comments

Comments
 (0)