aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/postmaster/bgworker.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c
index 2d2c450ba35..c40410d73ea 100644
--- a/src/backend/postmaster/bgworker.c
+++ b/src/backend/postmaster/bgworker.c
@@ -327,9 +327,11 @@ BackgroundWorkerStateChange(bool allow_new_workers)
notify_pid = slot->worker.bgw_notify_pid;
if ((slot->worker.bgw_flags & BGWORKER_CLASS_PARALLEL) != 0)
BackgroundWorkerData->parallel_terminate_count++;
- pg_memory_barrier();
slot->pid = 0;
+
+ pg_memory_barrier();
slot->in_use = false;
+
if (notify_pid != 0)
kill(notify_pid, SIGUSR1);
@@ -416,6 +418,8 @@ BackgroundWorkerStateChange(bool allow_new_workers)
* points to it. This convention allows deletion of workers during
* searches of the worker list, and saves having to search the list again.
*
+ * Caller is responsible for notifying bgw_notify_pid, if appropriate.
+ *
* This function must be invoked only in the postmaster.
*/
void
@@ -428,9 +432,16 @@ ForgetBackgroundWorker(slist_mutable_iter *cur)
Assert(rw->rw_shmem_slot < max_worker_processes);
slot = &BackgroundWorkerData->slot[rw->rw_shmem_slot];
+ Assert(slot->in_use);
+
+ /*
+ * We need a memory barrier here to make sure that the update of
+ * parallel_terminate_count completes before the store to in_use.
+ */
if ((rw->rw_worker.bgw_flags & BGWORKER_CLASS_PARALLEL) != 0)
BackgroundWorkerData->parallel_terminate_count++;
+ pg_memory_barrier();
slot->in_use = false;
ereport(DEBUG1,