PostgreSQL Source Code git master
pmchild.c File Reference
#include "postgres.h"
#include "miscadmin.h"
#include "postmaster/autovacuum.h"
#include "postmaster/postmaster.h"
#include "replication/walsender.h"
#include "storage/pmsignal.h"
#include "storage/proc.h"
Include dependency graph for pmchild.c:

Go to the source code of this file.

Data Structures

struct  PMChildPool
 

Typedefs

typedef struct PMChildPool PMChildPool
 

Functions

int MaxLivePostmasterChildren (void)
 
void InitPostmasterChildSlots (void)
 
PMChildAssignPostmasterChildSlot (BackendType btype)
 
PMChildAllocDeadEndChild (void)
 
bool ReleasePostmasterChildSlot (PMChild *pmchild)
 
PMChildFindPostmasterChildByPid (int pid)
 

Variables

static PMChildPool pmchild_pools [BACKEND_NUM_TYPES]
 
NON_EXEC_STATIC int num_pmchild_slots = 0
 
dlist_head ActiveChildList
 

Typedef Documentation

◆ PMChildPool

typedef struct PMChildPool PMChildPool

Function Documentation

◆ AllocDeadEndChild()

PMChild * AllocDeadEndChild ( void  )

Definition at line 207 of file pmchild.c.

208{
209 PMChild *pmchild;
210
211 elog(DEBUG2, "allocating dead-end child");
212
213 pmchild = (PMChild *) palloc_extended(sizeof(PMChild), MCXT_ALLOC_NO_OOM);
214 if (pmchild)
215 {
216 pmchild->pid = 0;
217 pmchild->child_slot = 0;
219 pmchild->rw = NULL;
220 pmchild->bgworker_notify = false;
221
223 }
224
225 return pmchild;
226}
#define DEBUG2
Definition: elog.h:29
#define elog(elevel,...)
Definition: elog.h:225
#define MCXT_ALLOC_NO_OOM
Definition: fe_memutils.h:29
static void dlist_push_head(dlist_head *head, dlist_node *node)
Definition: ilist.h:347
void * palloc_extended(Size size, int flags)
Definition: mcxt.c:1368
@ B_DEAD_END_BACKEND
Definition: miscadmin.h:342
dlist_head ActiveChildList
Definition: pmchild.c:60
struct RegisteredBgWorker * rw
Definition: postmaster.h:45
bool bgworker_notify
Definition: postmaster.h:46
BackendType bkend_type
Definition: postmaster.h:44
dlist_node elem
Definition: postmaster.h:47
pid_t pid
Definition: postmaster.h:42
int child_slot
Definition: postmaster.h:43

References ActiveChildList, B_DEAD_END_BACKEND, PMChild::bgworker_notify, PMChild::bkend_type, PMChild::child_slot, DEBUG2, dlist_push_head(), PMChild::elem, elog, MCXT_ALLOC_NO_OOM, palloc_extended(), PMChild::pid, and PMChild::rw.

Referenced by BackendStartup().

◆ AssignPostmasterChildSlot()

PMChild * AssignPostmasterChildSlot ( BackendType  btype)

Definition at line 161 of file pmchild.c.

162{
163 dlist_head *freelist;
164 PMChild *pmchild;
165
166 if (pmchild_pools[btype].size == 0)
167 elog(ERROR, "cannot allocate a PMChild slot for backend type %d", btype);
168
169 freelist = &pmchild_pools[btype].freelist;
170 if (dlist_is_empty(freelist))
171 return NULL;
172
173 pmchild = dlist_container(PMChild, elem, dlist_pop_head_node(freelist));
174 pmchild->pid = 0;
175 pmchild->bkend_type = btype;
176 pmchild->rw = NULL;
177 pmchild->bgworker_notify = true;
178
179 /*
180 * pmchild->child_slot for each entry was initialized when the array of
181 * slots was allocated. Sanity check it.
182 */
183 if (!(pmchild->child_slot >= pmchild_pools[btype].first_slotno &&
184 pmchild->child_slot < pmchild_pools[btype].first_slotno + pmchild_pools[btype].size))
185 {
186 elog(ERROR, "pmchild freelist for backend type %d is corrupt",
187 pmchild->bkend_type);
188 }
189
191
192 /* Update the status in the shared memory array */
194
195 elog(DEBUG2, "assigned pm child slot %d for %s",
196 pmchild->child_slot, PostmasterChildName(btype));
197
198 return pmchild;
199}
#define ERROR
Definition: elog.h:39
static dlist_node * dlist_pop_head_node(dlist_head *head)
Definition: ilist.h:450
static bool dlist_is_empty(const dlist_head *head)
Definition: ilist.h:336
#define dlist_container(type, membername, ptr)
Definition: ilist.h:593
const char * PostmasterChildName(BackendType child_type)
static PMChildPool pmchild_pools[BACKEND_NUM_TYPES]
Definition: pmchild.c:54
void MarkPostmasterChildSlotAssigned(int slot)
Definition: pmsignal.c:230
static pg_noinline void Size size
Definition: slab.c:607
int first_slotno
Definition: pmchild.c:50
int size
Definition: pmchild.c:48
dlist_head freelist
Definition: pmchild.c:51

References ActiveChildList, PMChild::bgworker_notify, PMChild::bkend_type, PMChild::child_slot, DEBUG2, dlist_container, dlist_is_empty(), dlist_pop_head_node(), dlist_push_head(), PMChild::elem, elog, ERROR, PMChildPool::first_slotno, PMChildPool::freelist, MarkPostmasterChildSlotAssigned(), PMChild::pid, pmchild_pools, PostmasterChildName(), PMChild::rw, PMChildPool::size, and size.

Referenced by BackendStartup(), StartBackgroundWorker(), StartChildProcess(), and StartSysLogger().

◆ FindPostmasterChildByPid()

PMChild * FindPostmasterChildByPid ( int  pid)

Definition at line 273 of file pmchild.c.

274{
275 dlist_iter iter;
276
278 {
279 PMChild *bp = dlist_container(PMChild, elem, iter.cur);
280
281 if (bp->pid == pid)
282 return bp;
283 }
284 return NULL;
285}
#define dlist_foreach(iter, lhead)
Definition: ilist.h:623
dlist_node * cur
Definition: ilist.h:179

References ActiveChildList, dlist_iter::cur, dlist_container, dlist_foreach, and PMChild::pid.

Referenced by process_pm_child_exit().

◆ InitPostmasterChildSlots()

void InitPostmasterChildSlots ( void  )

Definition at line 86 of file pmchild.c.

87{
88 int slotno;
89 PMChild *slots;
90
91 /*
92 * We allow more connections here than we can have backends because some
93 * might still be authenticating; they might fail auth, or some existing
94 * backend might exit before the auth cycle is completed. The exact
95 * MaxConnections limit is enforced when a new backend tries to join the
96 * PGPROC array.
97 *
98 * WAL senders start out as regular backends, so they share the same pool.
99 */
101
104
105 /*
106 * There can be only one of each of these running at a time. They each
107 * get their own pool of just one entry.
108 */
119
120 /* The rest of the pmchild_pools are left at zero size */
121
122 /* Count the total number of slots */
124 for (int i = 0; i < BACKEND_NUM_TYPES; i++)
126
127 /* Initialize them */
128 slots = palloc(num_pmchild_slots * sizeof(PMChild));
129 slotno = 0;
130 for (int btype = 0; btype < BACKEND_NUM_TYPES; btype++)
131 {
132 pmchild_pools[btype].first_slotno = slotno + 1;
133 dlist_init(&pmchild_pools[btype].freelist);
134
135 for (int j = 0; j < pmchild_pools[btype].size; j++)
136 {
137 slots[slotno].pid = 0;
138 slots[slotno].child_slot = slotno + 1;
139 slots[slotno].bkend_type = B_INVALID;
140 slots[slotno].rw = NULL;
141 slots[slotno].bgworker_notify = false;
142 dlist_push_tail(&pmchild_pools[btype].freelist, &slots[slotno].elem);
143 slotno++;
144 }
145 }
146 Assert(slotno == num_pmchild_slots);
147
148 /* Initialize other structures */
150}
int autovacuum_worker_slots
Definition: autovacuum.c:118
#define Assert(condition)
Definition: c.h:815
int MaxConnections
Definition: globals.c:142
int max_worker_processes
Definition: globals.c:143
static void dlist_init(dlist_head *head)
Definition: ilist.h:314
static void dlist_push_tail(dlist_head *head, dlist_node *node)
Definition: ilist.h:364
int j
Definition: isn.c:73
int i
Definition: isn.c:72
void * palloc(Size size)
Definition: mcxt.c:1317
#define BACKEND_NUM_TYPES
Definition: miscadmin.h:375
@ B_WAL_SUMMARIZER
Definition: miscadmin.h:365
@ B_WAL_WRITER
Definition: miscadmin.h:366
@ B_WAL_RECEIVER
Definition: miscadmin.h:364
@ B_CHECKPOINTER
Definition: miscadmin.h:362
@ B_LOGGER
Definition: miscadmin.h:372
@ B_STARTUP
Definition: miscadmin.h:363
@ B_BG_WORKER
Definition: miscadmin.h:345
@ B_INVALID
Definition: miscadmin.h:338
@ B_BG_WRITER
Definition: miscadmin.h:361
@ B_BACKEND
Definition: miscadmin.h:341
@ B_ARCHIVER
Definition: miscadmin.h:360
@ B_AUTOVAC_LAUNCHER
Definition: miscadmin.h:343
@ B_SLOTSYNC_WORKER
Definition: miscadmin.h:347
@ B_AUTOVAC_WORKER
Definition: miscadmin.h:344
NON_EXEC_STATIC int num_pmchild_slots
Definition: pmchild.c:55
int max_wal_senders
Definition: walsender.c:121

References ActiveChildList, Assert, autovacuum_worker_slots, B_ARCHIVER, B_AUTOVAC_LAUNCHER, B_AUTOVAC_WORKER, B_BACKEND, B_BG_WORKER, B_BG_WRITER, B_CHECKPOINTER, B_INVALID, B_LOGGER, B_SLOTSYNC_WORKER, B_STARTUP, B_WAL_RECEIVER, B_WAL_SUMMARIZER, B_WAL_WRITER, BACKEND_NUM_TYPES, PMChild::bgworker_notify, PMChild::bkend_type, PMChild::child_slot, dlist_init(), dlist_push_tail(), PMChildPool::first_slotno, i, j, max_wal_senders, max_worker_processes, MaxConnections, num_pmchild_slots, palloc(), PMChild::pid, pmchild_pools, PMChild::rw, PMChildPool::size, and size.

Referenced by BootstrapModeMain(), PostgresSingleUserMain(), and PostmasterMain().

◆ MaxLivePostmasterChildren()

int MaxLivePostmasterChildren ( void  )

Definition at line 70 of file pmchild.c.

71{
72 if (num_pmchild_slots == 0)
73 elog(ERROR, "PM child array not initialized yet");
74 return num_pmchild_slots;
75}

References elog, ERROR, and num_pmchild_slots.

Referenced by PMSignalShmemInit(), and PMSignalShmemSize().

◆ ReleasePostmasterChildSlot()

bool ReleasePostmasterChildSlot ( PMChild pmchild)

Definition at line 235 of file pmchild.c.

236{
237 dlist_delete(&pmchild->elem);
238 if (pmchild->bkend_type == B_DEAD_END_BACKEND)
239 {
240 elog(DEBUG2, "releasing dead-end backend");
241 pfree(pmchild);
242 return true;
243 }
244 else
245 {
246 PMChildPool *pool;
247
248 elog(DEBUG2, "releasing pm child slot %d", pmchild->child_slot);
249
250 /* WAL senders start out as regular backends, and share the pool */
251 if (pmchild->bkend_type == B_WAL_SENDER)
252 pool = &pmchild_pools[B_BACKEND];
253 else
254 pool = &pmchild_pools[pmchild->bkend_type];
255
256 /* sanity check that we return the entry to the right pool */
257 if (!(pmchild->child_slot >= pool->first_slotno &&
258 pmchild->child_slot < pool->first_slotno + pool->size))
259 {
260 elog(ERROR, "pmchild freelist for backend type %d is corrupt",
261 pmchild->bkend_type);
262 }
263
264 dlist_push_head(&pool->freelist, &pmchild->elem);
266 }
267}
static void dlist_delete(dlist_node *node)
Definition: ilist.h:405
void pfree(void *pointer)
Definition: mcxt.c:1521
@ B_WAL_SENDER
Definition: miscadmin.h:346
bool MarkPostmasterChildSlotUnassigned(int slot)
Definition: pmsignal.c:249

References B_BACKEND, B_DEAD_END_BACKEND, B_WAL_SENDER, PMChild::bkend_type, PMChild::child_slot, DEBUG2, dlist_delete(), dlist_push_head(), PMChild::elem, elog, ERROR, PMChildPool::first_slotno, PMChildPool::freelist, MarkPostmasterChildSlotUnassigned(), pfree(), pmchild_pools, and PMChildPool::size.

Referenced by BackendStartup(), CleanupBackend(), process_pm_child_exit(), StartBackgroundWorker(), StartChildProcess(), and StartSysLogger().

Variable Documentation

◆ ActiveChildList

◆ num_pmchild_slots

NON_EXEC_STATIC int num_pmchild_slots = 0

Definition at line 55 of file pmchild.c.

Referenced by InitPostmasterChildSlots(), and MaxLivePostmasterChildren().

◆ pmchild_pools