Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 76d07a2

Browse files
committed
Fix status reporting for terminated bgworkers that were never started.
Previously, GetBackgroundWorkerPid() would return BGWH_NOT_YET_STARTED if the slot used for the worker registration had not been reused by unrelated activity, and BGWH_STOPPED if it had. Either way, a process that had requested notification when the state of one of its background workers changed did not receive such notifications. Fix things so that GetBackgroundWorkerPid() always returns BGWH_STOPPED in this situation, so that we do not erroneously give waiters the impression that the worker will eventually be started; and send notifications just as we would if the process terminated after having been started, so that it's possible to wait for the postmaster to process a worker termination request without polling. Discovered by Amit Kapila during testing of parallel sequential scan. Analysis and fix by me. Back-patch to 9.4; there may not be anyone relying on this interface yet, but if anyone is, the new behavior is a clear improvement.
1 parent 904e8b6 commit 76d07a2

File tree

1 file changed

+24
-1
lines changed

1 file changed

+24
-1
lines changed

src/backend/postmaster/bgworker.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,14 +245,37 @@ BackgroundWorkerStateChange(void)
245245
rw->rw_terminate = true;
246246
if (rw->rw_pid != 0)
247247
kill(rw->rw_pid, SIGTERM);
248+
else
249+
{
250+
/* Report never-started, now-terminated worker as dead. */
251+
ReportBackgroundWorkerPID(rw);
252+
}
248253
}
249254
continue;
250255
}
251256

252-
/* If it's already flagged as do not restart, just release the slot. */
257+
/*
258+
* If the worker is marked for termination, we don't need to add it
259+
* to the registered workers list; we can just free the slot.
260+
* However, if bgw_notify_pid is set, the process that registered the
261+
* worker may need to know that we've processed the terminate request,
262+
* so be sure to signal it.
263+
*/
253264
if (slot->terminate)
254265
{
266+
int notify_pid;
267+
268+
/*
269+
* We need a memory barrier here to make sure that the load of
270+
* bgw_notify_pid completes before the store to in_use.
271+
*/
272+
notify_pid = slot->worker.bgw_notify_pid;
273+
pg_memory_barrier();
274+
slot->pid = 0;
255275
slot->in_use = false;
276+
if (notify_pid != 0)
277+
kill(notify_pid, SIGUSR1);
278+
256279
continue;
257280
}
258281

0 commit comments

Comments
 (0)