@@ -584,12 +584,14 @@ partition_table_concurrently(PG_FUNCTION_ARGS)
584
584
#define tostr (str ) ( #str )/* convert function's name to literal */
585
585
586
586
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? */
588
588
int i ;
589
589
590
590
/* Check if relation is a partitioned table */
591
591
shout_if_prel_is_invalid (relid ,
592
+ /* We also lock the parent relation */
592
593
get_pathman_relation_info_after_lock (relid , true),
594
+ /* Partitioning type does not matter here */
593
595
PT_INDIFFERENT );
594
596
595
597
/*
@@ -601,30 +603,38 @@ partition_table_concurrently(PG_FUNCTION_ARGS)
601
603
ConcurrentPartSlot * cur_slot = & concurrent_part_slots [i ];
602
604
bool keep_this_lock = false;
603
605
606
+ /* Lock current slot */
604
607
SpinLockAcquire (& cur_slot -> mutex );
605
608
606
- /* Should we take this slot into account? */
609
+ /* Should we take this slot into account?(it should be FREE) */
607
610
if (empty_slot_idx < 0 && cur_slot -> worker_status == CPS_FREE )
608
611
{
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 */
611
614
}
612
615
616
+ /* Oops, looks like we already have BGWorker for this table */
613
617
if (cur_slot -> relid == relid &&
614
618
cur_slot -> dbid == MyDatabaseId )
615
619
{
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 );
618
626
619
627
elog (ERROR ,
620
628
"Table \"%s\" is already being partitioned" ,
621
629
get_rel_name (relid ));
622
630
}
623
631
632
+ /* Normally we don't want to keep it */
624
633
if (!keep_this_lock )
625
634
SpinLockRelease (& cur_slot -> mutex );
626
635
}
627
636
637
+ /* Looks like we could not find an empty slot */
628
638
if (empty_slot_idx < 0 )
629
639
elog (ERROR ,"No empty worker slots found" );
630
640
else
@@ -634,6 +644,7 @@ partition_table_concurrently(PG_FUNCTION_ARGS)
634
644
GetAuthenticatedUserId (),CPS_WORKING ,
635
645
MyDatabaseId ,relid ,1000 ,1.0 );
636
646
647
+ /* Now we can safely unlock slot for new BGWorker */
637
648
SpinLockRelease (& concurrent_part_slots [empty_slot_idx ].mutex );
638
649
}
639
650