Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)