/*
* The postmaster's list of registered background workers, in private memory.
*/
-slist_head BackgroundWorkerList = SLIST_STATIC_INIT(BackgroundWorkerList);
+dlist_head BackgroundWorkerList = DLIST_STATIC_INIT(BackgroundWorkerList);
/*
* BackgroundWorkerSlots exist in shared memory and can be accessed (via
&found);
if (!IsUnderPostmaster)
{
- slist_iter siter;
+ dlist_iter iter;
int slotno = 0;
BackgroundWorkerData->total_slots = max_worker_processes;
* correspondence between the postmaster's private list and the array
* in shared memory.
*/
- slist_foreach(siter, &BackgroundWorkerList)
+ dlist_foreach(iter, &BackgroundWorkerList)
{
BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno];
RegisteredBgWorker *rw;
- rw = slist_container(RegisteredBgWorker, rw_lnode, siter.cur);
+ rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
Assert(slotno < max_worker_processes);
slot->in_use = true;
slot->terminate = false;
static RegisteredBgWorker *
FindRegisteredWorkerBySlotNumber(int slotno)
{
- slist_iter siter;
+ dlist_iter iter;
- slist_foreach(siter, &BackgroundWorkerList)
+ dlist_foreach(iter, &BackgroundWorkerList)
{
RegisteredBgWorker *rw;
- rw = slist_container(RegisteredBgWorker, rw_lnode, siter.cur);
+ rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
if (rw->rw_shmem_slot == slotno)
return rw;
}
(errmsg_internal("registering background worker \"%s\"",
rw->rw_worker.bgw_name)));
- slist_push_head(&BackgroundWorkerList, &rw->rw_lnode);
+ dlist_push_head(&BackgroundWorkerList, &rw->rw_lnode);
}
}
/*
* Forget about a background worker that's no longer needed.
*
- * The worker must be identified by passing an slist_mutable_iter that
- * points to it. This convention allows deletion of workers during
- * searches of the worker list, and saves having to search the list again.
+ * NOTE: The entry is unlinked from BackgroundWorkerList. If the caller is
+ * iterating through it, better use a mutable iterator!
*
* Caller is responsible for notifying bgw_notify_pid, if appropriate.
*
* This function must be invoked only in the postmaster.
*/
void
-ForgetBackgroundWorker(slist_mutable_iter *cur)
+ForgetBackgroundWorker(RegisteredBgWorker *rw)
{
- RegisteredBgWorker *rw;
BackgroundWorkerSlot *slot;
- rw = slist_container(RegisteredBgWorker, rw_lnode, cur->cur);
-
Assert(rw->rw_shmem_slot < max_worker_processes);
slot = &BackgroundWorkerData->slot[rw->rw_shmem_slot];
Assert(slot->in_use);
(errmsg_internal("unregistering background worker \"%s\"",
rw->rw_worker.bgw_name)));
- slist_delete_current(cur);
+ dlist_delete(&rw->rw_lnode);
pfree(rw);
}
* Report that the PID of a background worker is now zero because a
* previously-running background worker has exited.
*
+ * NOTE: The entry may be unlinked from BackgroundWorkerList. If the caller
+ * is iterating through it, better use a mutable iterator!
+ *
* This function should only be called from the postmaster.
*/
void
-ReportBackgroundWorkerExit(slist_mutable_iter *cur)
+ReportBackgroundWorkerExit(RegisteredBgWorker *rw)
{
- RegisteredBgWorker *rw;
BackgroundWorkerSlot *slot;
int notify_pid;
- rw = slist_container(RegisteredBgWorker, rw_lnode, cur->cur);
-
Assert(rw->rw_shmem_slot < max_worker_processes);
slot = &BackgroundWorkerData->slot[rw->rw_shmem_slot];
slot->pid = rw->rw_pid;
*/
if (rw->rw_terminate ||
rw->rw_worker.bgw_restart_time == BGW_NEVER_RESTART)
- ForgetBackgroundWorker(cur);
+ ForgetBackgroundWorker(rw);
if (notify_pid != 0)
kill(notify_pid, SIGUSR1);
void
BackgroundWorkerStopNotifications(pid_t pid)
{
- slist_iter siter;
+ dlist_iter iter;
- slist_foreach(siter, &BackgroundWorkerList)
+ dlist_foreach(iter, &BackgroundWorkerList)
{
RegisteredBgWorker *rw;
- rw = slist_container(RegisteredBgWorker, rw_lnode, siter.cur);
+ rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
if (rw->rw_worker.bgw_notify_pid == pid)
rw->rw_worker.bgw_notify_pid = 0;
}
void
ForgetUnstartedBackgroundWorkers(void)
{
- slist_mutable_iter iter;
+ dlist_mutable_iter iter;
- slist_foreach_modify(iter, &BackgroundWorkerList)
+ dlist_foreach_modify(iter, &BackgroundWorkerList)
{
RegisteredBgWorker *rw;
BackgroundWorkerSlot *slot;
- rw = slist_container(RegisteredBgWorker, rw_lnode, iter.cur);
+ rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
Assert(rw->rw_shmem_slot < max_worker_processes);
slot = &BackgroundWorkerData->slot[rw->rw_shmem_slot];
/* ... then zap it, and notify the waiter */
int notify_pid = rw->rw_worker.bgw_notify_pid;
- ForgetBackgroundWorker(&iter);
+ ForgetBackgroundWorker(rw);
if (notify_pid != 0)
kill(notify_pid, SIGUSR1);
}
void
ResetBackgroundWorkerCrashTimes(void)
{
- slist_mutable_iter iter;
+ dlist_mutable_iter iter;
- slist_foreach_modify(iter, &BackgroundWorkerList)
+ dlist_foreach_modify(iter, &BackgroundWorkerList)
{
RegisteredBgWorker *rw;
- rw = slist_container(RegisteredBgWorker, rw_lnode, iter.cur);
+ rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
if (rw->rw_worker.bgw_restart_time == BGW_NEVER_RESTART)
{
* parallel_terminate_count will get incremented after we've
* already zeroed parallel_register_count, which would be bad.)
*/
- ForgetBackgroundWorker(&iter);
+ ForgetBackgroundWorker(rw);
}
else
{
rw->rw_crashed_at = 0;
rw->rw_terminate = false;
- slist_push_head(&BackgroundWorkerList, &rw->rw_lnode);
+ dlist_push_head(&BackgroundWorkerList, &rw->rw_lnode);
}
/*
if (HaveCrashedWorker)
{
- slist_mutable_iter siter;
+ dlist_mutable_iter iter;
/*
* When there are crashed bgworkers, we sleep just long enough that
* determine the minimum of all wakeup times according to most recent
* crash time and requested restart interval.
*/
- slist_foreach_modify(siter, &BackgroundWorkerList)
+ dlist_foreach_modify(iter, &BackgroundWorkerList)
{
RegisteredBgWorker *rw;
TimestampTz this_wakeup;
- rw = slist_container(RegisteredBgWorker, rw_lnode, siter.cur);
+ rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
if (rw->rw_crashed_at == 0)
continue;
if (rw->rw_worker.bgw_restart_time == BGW_NEVER_RESTART
|| rw->rw_terminate)
{
- ForgetBackgroundWorker(&siter);
+ ForgetBackgroundWorker(rw);
continue;
}
int exitstatus) /* child's exit status */
{
char namebuf[MAXPGPATH];
- slist_mutable_iter iter;
+ dlist_mutable_iter iter;
- slist_foreach_modify(iter, &BackgroundWorkerList)
+ dlist_foreach_modify(iter, &BackgroundWorkerList)
{
RegisteredBgWorker *rw;
- rw = slist_container(RegisteredBgWorker, rw_lnode, iter.cur);
+ rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
if (rw->rw_pid != pid)
continue;
rw->rw_backend = NULL;
rw->rw_pid = 0;
rw->rw_child_slot = 0;
- ReportBackgroundWorkerExit(&iter); /* report child death */
+ ReportBackgroundWorkerExit(rw); /* report child death */
LogChildExit(EXIT_STATUS_0(exitstatus) ? DEBUG1 : LOG,
namebuf, pid, exitstatus);
static void
HandleChildCrash(int pid, int exitstatus, const char *procname)
{
- dlist_mutable_iter iter;
- slist_iter siter;
+ dlist_iter iter;
+ dlist_mutable_iter miter;
Backend *bp;
bool take_action;
}
/* Process background workers. */
- slist_foreach(siter, &BackgroundWorkerList)
+ dlist_foreach(iter, &BackgroundWorkerList)
{
RegisteredBgWorker *rw;
- rw = slist_container(RegisteredBgWorker, rw_lnode, siter.cur);
+ rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
if (rw->rw_pid == 0)
continue; /* not running */
if (rw->rw_pid == pid)
}
/* Process regular backends */
- dlist_foreach_modify(iter, &BackendList)
+ dlist_foreach_modify(miter, &BackendList)
{
- bp = dlist_container(Backend, elem, iter.cur);
+ bp = dlist_container(Backend, elem, miter.cur);
if (bp->pid == pid)
{
{
(void) ReleasePostmasterChildSlot(bp->child_slot);
}
- dlist_delete(iter.cur);
+ dlist_delete(miter.cur);
pfree(bp);
/* Keep looping so we can signal remaining backends */
}
#define MAX_BGWORKERS_TO_LAUNCH 100
int num_launched = 0;
TimestampTz now = 0;
- slist_mutable_iter iter;
+ dlist_mutable_iter iter;
/*
* During crash recovery, we have no need to be called until the state
StartWorkerNeeded = false;
HaveCrashedWorker = false;
- slist_foreach_modify(iter, &BackgroundWorkerList)
+ dlist_foreach_modify(iter, &BackgroundWorkerList)
{
RegisteredBgWorker *rw;
- rw = slist_container(RegisteredBgWorker, rw_lnode, iter.cur);
+ rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
/* ignore if already running */
if (rw->rw_pid != 0)
/* if marked for death, clean up and remove from list */
if (rw->rw_terminate)
{
- ForgetBackgroundWorker(&iter);
+ ForgetBackgroundWorker(rw);
continue;
}
notify_pid = rw->rw_worker.bgw_notify_pid;
- ForgetBackgroundWorker(&iter);
+ ForgetBackgroundWorker(rw);
/* Report worker is gone now. */
if (notify_pid != 0)