Skip to content

Commit b43100f

Browse files
committed
Make BackgroundWorkerList doubly-linked
This allows ForgetBackgroundWorker() and ReportBackgroundWorkerExit() to take a RegisteredBgWorker pointer as argument, rather than a list iterator. That feels a little more natural. But more importantly, this paves the way for more refactoring in the next commit. Reviewed-by: Thomas Munro <thomas.munro@gmail.com> Discussion: https://www.postgresql.org/message-id/835232c0-a5f7-4f20-b95b-5b56ba57d741@iki.fi
1 parent 7fceb57 commit b43100f

File tree

3 files changed

+54
-58
lines changed

3 files changed

+54
-58
lines changed

src/backend/postmaster/bgworker.c

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
/*
3838
* The postmaster's list of registered background workers, in private memory.
3939
*/
40-
slist_head BackgroundWorkerList = SLIST_STATIC_INIT(BackgroundWorkerList);
40+
dlist_head BackgroundWorkerList = DLIST_STATIC_INIT(BackgroundWorkerList);
4141

4242
/*
4343
* BackgroundWorkerSlots exist in shared memory and can be accessed (via
@@ -168,7 +168,7 @@ BackgroundWorkerShmemInit(void)
168168
&found);
169169
if (!IsUnderPostmaster)
170170
{
171-
slist_iter siter;
171+
dlist_iter iter;
172172
int slotno = 0;
173173

174174
BackgroundWorkerData->total_slots = max_worker_processes;
@@ -181,12 +181,12 @@ BackgroundWorkerShmemInit(void)
181181
* correspondence between the postmaster's private list and the array
182182
* in shared memory.
183183
*/
184-
slist_foreach(siter, &BackgroundWorkerList)
184+
dlist_foreach(iter, &BackgroundWorkerList)
185185
{
186186
BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno];
187187
RegisteredBgWorker *rw;
188188

189-
rw = slist_container(RegisteredBgWorker, rw_lnode, siter.cur);
189+
rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
190190
Assert(slotno < max_worker_processes);
191191
slot->in_use = true;
192192
slot->terminate = false;
@@ -220,13 +220,13 @@ BackgroundWorkerShmemInit(void)
220220
static RegisteredBgWorker *
221221
FindRegisteredWorkerBySlotNumber(int slotno)
222222
{
223-
slist_iter siter;
223+
dlist_iter iter;
224224

225-
slist_foreach(siter, &BackgroundWorkerList)
225+
dlist_foreach(iter, &BackgroundWorkerList)
226226
{
227227
RegisteredBgWorker *rw;
228228

229-
rw = slist_container(RegisteredBgWorker, rw_lnode, siter.cur);
229+
rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
230230
if (rw->rw_shmem_slot == slotno)
231231
return rw;
232232
}
@@ -413,29 +413,25 @@ BackgroundWorkerStateChange(bool allow_new_workers)
413413
(errmsg_internal("registering background worker \"%s\"",
414414
rw->rw_worker.bgw_name)));
415415

416-
slist_push_head(&BackgroundWorkerList, &rw->rw_lnode);
416+
dlist_push_head(&BackgroundWorkerList, &rw->rw_lnode);
417417
}
418418
}
419419

420420
/*
421421
* Forget about a background worker that's no longer needed.
422422
*
423-
* The worker must be identified by passing an slist_mutable_iter that
424-
* points to it. This convention allows deletion of workers during
425-
* searches of the worker list, and saves having to search the list again.
423+
* NOTE: The entry is unlinked from BackgroundWorkerList. If the caller is
424+
* iterating through it, better use a mutable iterator!
426425
*
427426
* Caller is responsible for notifying bgw_notify_pid, if appropriate.
428427
*
429428
* This function must be invoked only in the postmaster.
430429
*/
431430
void
432-
ForgetBackgroundWorker(slist_mutable_iter *cur)
431+
ForgetBackgroundWorker(RegisteredBgWorker *rw)
433432
{
434-
RegisteredBgWorker *rw;
435433
BackgroundWorkerSlot *slot;
436434

437-
rw = slist_container(RegisteredBgWorker, rw_lnode, cur->cur);
438-
439435
Assert(rw->rw_shmem_slot < max_worker_processes);
440436
slot = &BackgroundWorkerData->slot[rw->rw_shmem_slot];
441437
Assert(slot->in_use);
@@ -454,7 +450,7 @@ ForgetBackgroundWorker(slist_mutable_iter *cur)
454450
(errmsg_internal("unregistering background worker \"%s\"",
455451
rw->rw_worker.bgw_name)));
456452

457-
slist_delete_current(cur);
453+
dlist_delete(&rw->rw_lnode);
458454
pfree(rw);
459455
}
460456

@@ -480,17 +476,17 @@ ReportBackgroundWorkerPID(RegisteredBgWorker *rw)
480476
* Report that the PID of a background worker is now zero because a
481477
* previously-running background worker has exited.
482478
*
479+
* NOTE: The entry may be unlinked from BackgroundWorkerList. If the caller
480+
* is iterating through it, better use a mutable iterator!
481+
*
483482
* This function should only be called from the postmaster.
484483
*/
485484
void
486-
ReportBackgroundWorkerExit(slist_mutable_iter *cur)
485+
ReportBackgroundWorkerExit(RegisteredBgWorker *rw)
487486
{
488-
RegisteredBgWorker *rw;
489487
BackgroundWorkerSlot *slot;
490488
int notify_pid;
491489

492-
rw = slist_container(RegisteredBgWorker, rw_lnode, cur->cur);
493-
494490
Assert(rw->rw_shmem_slot < max_worker_processes);
495491
slot = &BackgroundWorkerData->slot[rw->rw_shmem_slot];
496492
slot->pid = rw->rw_pid;
@@ -505,7 +501,7 @@ ReportBackgroundWorkerExit(slist_mutable_iter *cur)
505501
*/
506502
if (rw->rw_terminate ||
507503
rw->rw_worker.bgw_restart_time == BGW_NEVER_RESTART)
508-
ForgetBackgroundWorker(cur);
504+
ForgetBackgroundWorker(rw);
509505

510506
if (notify_pid != 0)
511507
kill(notify_pid, SIGUSR1);
@@ -519,13 +515,13 @@ ReportBackgroundWorkerExit(slist_mutable_iter *cur)
519515
void
520516
BackgroundWorkerStopNotifications(pid_t pid)
521517
{
522-
slist_iter siter;
518+
dlist_iter iter;
523519

524-
slist_foreach(siter, &BackgroundWorkerList)
520+
dlist_foreach(iter, &BackgroundWorkerList)
525521
{
526522
RegisteredBgWorker *rw;
527523

528-
rw = slist_container(RegisteredBgWorker, rw_lnode, siter.cur);
524+
rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
529525
if (rw->rw_worker.bgw_notify_pid == pid)
530526
rw->rw_worker.bgw_notify_pid = 0;
531527
}
@@ -546,14 +542,14 @@ BackgroundWorkerStopNotifications(pid_t pid)
546542
void
547543
ForgetUnstartedBackgroundWorkers(void)
548544
{
549-
slist_mutable_iter iter;
545+
dlist_mutable_iter iter;
550546

551-
slist_foreach_modify(iter, &BackgroundWorkerList)
547+
dlist_foreach_modify(iter, &BackgroundWorkerList)
552548
{
553549
RegisteredBgWorker *rw;
554550
BackgroundWorkerSlot *slot;
555551

556-
rw = slist_container(RegisteredBgWorker, rw_lnode, iter.cur);
552+
rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
557553
Assert(rw->rw_shmem_slot < max_worker_processes);
558554
slot = &BackgroundWorkerData->slot[rw->rw_shmem_slot];
559555

@@ -564,7 +560,7 @@ ForgetUnstartedBackgroundWorkers(void)
564560
/* ... then zap it, and notify the waiter */
565561
int notify_pid = rw->rw_worker.bgw_notify_pid;
566562

567-
ForgetBackgroundWorker(&iter);
563+
ForgetBackgroundWorker(rw);
568564
if (notify_pid != 0)
569565
kill(notify_pid, SIGUSR1);
570566
}
@@ -584,13 +580,13 @@ ForgetUnstartedBackgroundWorkers(void)
584580
void
585581
ResetBackgroundWorkerCrashTimes(void)
586582
{
587-
slist_mutable_iter iter;
583+
dlist_mutable_iter iter;
588584

589-
slist_foreach_modify(iter, &BackgroundWorkerList)
585+
dlist_foreach_modify(iter, &BackgroundWorkerList)
590586
{
591587
RegisteredBgWorker *rw;
592588

593-
rw = slist_container(RegisteredBgWorker, rw_lnode, iter.cur);
589+
rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
594590

595591
if (rw->rw_worker.bgw_restart_time == BGW_NEVER_RESTART)
596592
{
@@ -601,7 +597,7 @@ ResetBackgroundWorkerCrashTimes(void)
601597
* parallel_terminate_count will get incremented after we've
602598
* already zeroed parallel_register_count, which would be bad.)
603599
*/
604-
ForgetBackgroundWorker(&iter);
600+
ForgetBackgroundWorker(rw);
605601
}
606602
else
607603
{
@@ -1036,7 +1032,7 @@ RegisterBackgroundWorker(BackgroundWorker *worker)
10361032
rw->rw_crashed_at = 0;
10371033
rw->rw_terminate = false;
10381034

1039-
slist_push_head(&BackgroundWorkerList, &rw->rw_lnode);
1035+
dlist_push_head(&BackgroundWorkerList, &rw->rw_lnode);
10401036
}
10411037

10421038
/*

src/backend/postmaster/postmaster.c

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,28 +1531,28 @@ DetermineSleepTime(void)
15311531

15321532
if (HaveCrashedWorker)
15331533
{
1534-
slist_mutable_iter siter;
1534+
dlist_mutable_iter iter;
15351535

15361536
/*
15371537
* When there are crashed bgworkers, we sleep just long enough that
15381538
* they are restarted when they request to be. Scan the list to
15391539
* determine the minimum of all wakeup times according to most recent
15401540
* crash time and requested restart interval.
15411541
*/
1542-
slist_foreach_modify(siter, &BackgroundWorkerList)
1542+
dlist_foreach_modify(iter, &BackgroundWorkerList)
15431543
{
15441544
RegisteredBgWorker *rw;
15451545
TimestampTz this_wakeup;
15461546

1547-
rw = slist_container(RegisteredBgWorker, rw_lnode, siter.cur);
1547+
rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
15481548

15491549
if (rw->rw_crashed_at == 0)
15501550
continue;
15511551

15521552
if (rw->rw_worker.bgw_restart_time == BGW_NEVER_RESTART
15531553
|| rw->rw_terminate)
15541554
{
1555-
ForgetBackgroundWorker(&siter);
1555+
ForgetBackgroundWorker(rw);
15561556
continue;
15571557
}
15581558

@@ -2625,13 +2625,13 @@ CleanupBackgroundWorker(int pid,
26252625
int exitstatus) /* child's exit status */
26262626
{
26272627
char namebuf[MAXPGPATH];
2628-
slist_mutable_iter iter;
2628+
dlist_mutable_iter iter;
26292629

2630-
slist_foreach_modify(iter, &BackgroundWorkerList)
2630+
dlist_foreach_modify(iter, &BackgroundWorkerList)
26312631
{
26322632
RegisteredBgWorker *rw;
26332633

2634-
rw = slist_container(RegisteredBgWorker, rw_lnode, iter.cur);
2634+
rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
26352635

26362636
if (rw->rw_pid != pid)
26372637
continue;
@@ -2694,7 +2694,7 @@ CleanupBackgroundWorker(int pid,
26942694
rw->rw_backend = NULL;
26952695
rw->rw_pid = 0;
26962696
rw->rw_child_slot = 0;
2697-
ReportBackgroundWorkerExit(&iter); /* report child death */
2697+
ReportBackgroundWorkerExit(rw); /* report child death */
26982698

26992699
LogChildExit(EXIT_STATUS_0(exitstatus) ? DEBUG1 : LOG,
27002700
namebuf, pid, exitstatus);
@@ -2796,8 +2796,8 @@ CleanupBackend(int pid,
27962796
static void
27972797
HandleChildCrash(int pid, int exitstatus, const char *procname)
27982798
{
2799-
dlist_mutable_iter iter;
2800-
slist_iter siter;
2799+
dlist_iter iter;
2800+
dlist_mutable_iter miter;
28012801
Backend *bp;
28022802
bool take_action;
28032803

@@ -2819,11 +2819,11 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
28192819
}
28202820

28212821
/* Process background workers. */
2822-
slist_foreach(siter, &BackgroundWorkerList)
2822+
dlist_foreach(iter, &BackgroundWorkerList)
28232823
{
28242824
RegisteredBgWorker *rw;
28252825

2826-
rw = slist_container(RegisteredBgWorker, rw_lnode, siter.cur);
2826+
rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
28272827
if (rw->rw_pid == 0)
28282828
continue; /* not running */
28292829
if (rw->rw_pid == pid)
@@ -2853,9 +2853,9 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
28532853
}
28542854

28552855
/* Process regular backends */
2856-
dlist_foreach_modify(iter, &BackendList)
2856+
dlist_foreach_modify(miter, &BackendList)
28572857
{
2858-
bp = dlist_container(Backend, elem, iter.cur);
2858+
bp = dlist_container(Backend, elem, miter.cur);
28592859

28602860
if (bp->pid == pid)
28612861
{
@@ -2866,7 +2866,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
28662866
{
28672867
(void) ReleasePostmasterChildSlot(bp->child_slot);
28682868
}
2869-
dlist_delete(iter.cur);
2869+
dlist_delete(miter.cur);
28702870
pfree(bp);
28712871
/* Keep looping so we can signal remaining backends */
28722872
}
@@ -4177,7 +4177,7 @@ maybe_start_bgworkers(void)
41774177
#define MAX_BGWORKERS_TO_LAUNCH 100
41784178
int num_launched = 0;
41794179
TimestampTz now = 0;
4180-
slist_mutable_iter iter;
4180+
dlist_mutable_iter iter;
41814181

41824182
/*
41834183
* During crash recovery, we have no need to be called until the state
@@ -4194,11 +4194,11 @@ maybe_start_bgworkers(void)
41944194
StartWorkerNeeded = false;
41954195
HaveCrashedWorker = false;
41964196

4197-
slist_foreach_modify(iter, &BackgroundWorkerList)
4197+
dlist_foreach_modify(iter, &BackgroundWorkerList)
41984198
{
41994199
RegisteredBgWorker *rw;
42004200

4201-
rw = slist_container(RegisteredBgWorker, rw_lnode, iter.cur);
4201+
rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
42024202

42034203
/* ignore if already running */
42044204
if (rw->rw_pid != 0)
@@ -4207,7 +4207,7 @@ maybe_start_bgworkers(void)
42074207
/* if marked for death, clean up and remove from list */
42084208
if (rw->rw_terminate)
42094209
{
4210-
ForgetBackgroundWorker(&iter);
4210+
ForgetBackgroundWorker(rw);
42114211
continue;
42124212
}
42134213

@@ -4226,7 +4226,7 @@ maybe_start_bgworkers(void)
42264226

42274227
notify_pid = rw->rw_worker.bgw_notify_pid;
42284228

4229-
ForgetBackgroundWorker(&iter);
4229+
ForgetBackgroundWorker(rw);
42304230

42314231
/* Report worker is gone now. */
42324232
if (notify_pid != 0)

src/include/postmaster/bgworker_internals.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,17 @@ typedef struct RegisteredBgWorker
3939
TimestampTz rw_crashed_at; /* if not 0, time it last crashed */
4040
int rw_shmem_slot;
4141
bool rw_terminate;
42-
slist_node rw_lnode; /* list link */
42+
dlist_node rw_lnode; /* list link */
4343
} RegisteredBgWorker;
4444

45-
extern PGDLLIMPORT slist_head BackgroundWorkerList;
45+
extern PGDLLIMPORT dlist_head BackgroundWorkerList;
4646

4747
extern Size BackgroundWorkerShmemSize(void);
4848
extern void BackgroundWorkerShmemInit(void);
4949
extern void BackgroundWorkerStateChange(bool allow_new_workers);
50-
extern void ForgetBackgroundWorker(slist_mutable_iter *cur);
51-
extern void ReportBackgroundWorkerPID(RegisteredBgWorker *);
52-
extern void ReportBackgroundWorkerExit(slist_mutable_iter *cur);
50+
extern void ForgetBackgroundWorker(RegisteredBgWorker *rw);
51+
extern void ReportBackgroundWorkerPID(RegisteredBgWorker *rw);
52+
extern void ReportBackgroundWorkerExit(RegisteredBgWorker *rw);
5353
extern void BackgroundWorkerStopNotifications(pid_t pid);
5454
extern void ForgetUnstartedBackgroundWorkers(void);
5555
extern void ResetBackgroundWorkerCrashTimes(void);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy