PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
bgworker.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  BackgroundWorker
 

Macros

#define BGWORKER_SHMEM_ACCESS   0x0001
 
#define BGWORKER_BACKEND_DATABASE_CONNECTION   0x0002
 
#define BGWORKER_CLASS_PARALLEL   0x0010
 
#define BGW_DEFAULT_RESTART_INTERVAL   60
 
#define BGW_NEVER_RESTART   -1
 
#define BGW_MAXLEN   96
 
#define BGW_EXTRALEN   128
 
#define BGWORKER_BYPASS_ALLOWCONN   0x0001
 
#define BGWORKER_BYPASS_ROLELOGINCHECK   0x0002
 

Typedefs

typedef void(* bgworker_main_type) (Datum main_arg)
 
typedef struct BackgroundWorker BackgroundWorker
 
typedef enum BgwHandleStatus BgwHandleStatus
 
typedef struct BackgroundWorkerHandle BackgroundWorkerHandle
 

Enumerations

enum  BgWorkerStartTime { BgWorkerStart_PostmasterStart , BgWorkerStart_ConsistentState , BgWorkerStart_RecoveryFinished }
 
enum  BgwHandleStatus { BGWH_STARTED , BGWH_NOT_YET_STARTED , BGWH_STOPPED , BGWH_POSTMASTER_DIED }
 

Functions

void RegisterBackgroundWorker (BackgroundWorker *worker)
 
bool RegisterDynamicBackgroundWorker (BackgroundWorker *worker, BackgroundWorkerHandle **handle)
 
BgwHandleStatus GetBackgroundWorkerPid (BackgroundWorkerHandle *handle, pid_t *pidp)
 
BgwHandleStatus WaitForBackgroundWorkerStartup (BackgroundWorkerHandle *handle, pid_t *pidp)
 
BgwHandleStatus WaitForBackgroundWorkerShutdown (BackgroundWorkerHandle *)
 
const char * GetBackgroundWorkerTypeByPid (pid_t pid)
 
void TerminateBackgroundWorker (BackgroundWorkerHandle *handle)
 
void BackgroundWorkerInitializeConnection (const char *dbname, const char *username, uint32 flags)
 
void BackgroundWorkerInitializeConnectionByOid (Oid dboid, Oid useroid, uint32 flags)
 
void BackgroundWorkerBlockSignals (void)
 
void BackgroundWorkerUnblockSignals (void)
 

Variables

PGDLLIMPORT BackgroundWorkerMyBgworkerEntry
 

Macro Definition Documentation

◆ BGW_DEFAULT_RESTART_INTERVAL

#define BGW_DEFAULT_RESTART_INTERVAL   60

Definition at line 84 of file bgworker.h.

◆ BGW_EXTRALEN

#define BGW_EXTRALEN   128

Definition at line 87 of file bgworker.h.

◆ BGW_MAXLEN

#define BGW_MAXLEN   96

Definition at line 86 of file bgworker.h.

◆ BGW_NEVER_RESTART

#define BGW_NEVER_RESTART   -1

Definition at line 85 of file bgworker.h.

◆ BGWORKER_BACKEND_DATABASE_CONNECTION

#define BGWORKER_BACKEND_DATABASE_CONNECTION   0x0002

Definition at line 60 of file bgworker.h.

◆ BGWORKER_BYPASS_ALLOWCONN

#define BGWORKER_BYPASS_ALLOWCONN   0x0001

Definition at line 156 of file bgworker.h.

◆ BGWORKER_BYPASS_ROLELOGINCHECK

#define BGWORKER_BYPASS_ROLELOGINCHECK   0x0002

Definition at line 157 of file bgworker.h.

◆ BGWORKER_CLASS_PARALLEL

#define BGWORKER_CLASS_PARALLEL   0x0010

Definition at line 68 of file bgworker.h.

◆ BGWORKER_SHMEM_ACCESS

#define BGWORKER_SHMEM_ACCESS   0x0001

Definition at line 53 of file bgworker.h.

Typedef Documentation

◆ BackgroundWorker

◆ BackgroundWorkerHandle

Definition at line 112 of file bgworker.h.

◆ BgwHandleStatus

◆ bgworker_main_type

typedef void(* bgworker_main_type) (Datum main_arg)

Definition at line 72 of file bgworker.h.

Enumeration Type Documentation

◆ BgwHandleStatus

Enumerator
BGWH_STARTED 
BGWH_NOT_YET_STARTED 
BGWH_STOPPED 
BGWH_POSTMASTER_DIED 

Definition at line 103 of file bgworker.h.

104{
105 BGWH_STARTED, /* worker is running */
106 BGWH_NOT_YET_STARTED, /* worker hasn't been started yet */
107 BGWH_STOPPED, /* worker has exited */
108 BGWH_POSTMASTER_DIED, /* postmaster died; worker status unclear */
BgwHandleStatus
Definition: bgworker.h:104
@ BGWH_POSTMASTER_DIED
Definition: bgworker.h:108
@ BGWH_STARTED
Definition: bgworker.h:105
@ BGWH_NOT_YET_STARTED
Definition: bgworker.h:106
@ BGWH_STOPPED
Definition: bgworker.h:107

◆ BgWorkerStartTime

Enumerator
BgWorkerStart_PostmasterStart 
BgWorkerStart_ConsistentState 
BgWorkerStart_RecoveryFinished 

Definition at line 77 of file bgworker.h.

78{
BgWorkerStartTime
Definition: bgworker.h:78
@ BgWorkerStart_RecoveryFinished
Definition: bgworker.h:81
@ BgWorkerStart_ConsistentState
Definition: bgworker.h:80
@ BgWorkerStart_PostmasterStart
Definition: bgworker.h:79

Function Documentation

◆ BackgroundWorkerBlockSignals()

void BackgroundWorkerBlockSignals ( void  )

Definition at line 920 of file bgworker.c.

921{
922 sigprocmask(SIG_SETMASK, &BlockSig, NULL);
923}
sigset_t BlockSig
Definition: pqsignal.c:23

References BlockSig.

◆ BackgroundWorkerInitializeConnection()

void BackgroundWorkerInitializeConnection ( const char *  dbname,
const char *  username,
uint32  flags 
)

Definition at line 852 of file bgworker.c.

853{
855 bits32 init_flags = 0; /* never honor session_preload_libraries */
856
857 /* ignore datallowconn and ACL_CONNECT? */
858 if (flags & BGWORKER_BYPASS_ALLOWCONN)
859 init_flags |= INIT_PG_OVERRIDE_ALLOW_CONNS;
860 /* ignore rolcanlogin? */
862 init_flags |= INIT_PG_OVERRIDE_ROLE_LOGIN;
863
864 /* XXX is this the right errcode? */
867 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
868 errmsg("database connection requirement not indicated during registration")));
869
870 InitPostgres(dbname, InvalidOid, /* database to connect to */
871 username, InvalidOid, /* role to connect as */
872 init_flags,
873 NULL); /* no out_dbname */
874
875 /* it had better not gotten out of "init" mode yet */
878 (errmsg("invalid processing mode in background worker")));
880}
#define BGWORKER_BYPASS_ROLELOGINCHECK
Definition: bgworker.h:157
#define BGWORKER_BACKEND_DATABASE_CONNECTION
Definition: bgworker.h:60
#define BGWORKER_BYPASS_ALLOWCONN
Definition: bgworker.h:156
uint32 bits32
Definition: c.h:511
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define FATAL
Definition: elog.h:41
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
static char * username
Definition: initdb.c:153
@ NormalProcessing
Definition: miscadmin.h:472
#define IsInitProcessingMode()
Definition: miscadmin.h:478
#define SetProcessingMode(mode)
Definition: miscadmin.h:483
#define INIT_PG_OVERRIDE_ROLE_LOGIN
Definition: miscadmin.h:501
#define INIT_PG_OVERRIDE_ALLOW_CONNS
Definition: miscadmin.h:500
#define InvalidOid
Definition: postgres_ext.h:35
void InitPostgres(const char *in_dbname, Oid dboid, const char *username, Oid useroid, bits32 flags, char *out_dbname)
Definition: postinit.c:723
BackgroundWorker * MyBgworkerEntry
Definition: postmaster.c:200
char * dbname
Definition: streamutil.c:49

References BackgroundWorker::bgw_flags, BGWORKER_BACKEND_DATABASE_CONNECTION, BGWORKER_BYPASS_ALLOWCONN, BGWORKER_BYPASS_ROLELOGINCHECK, dbname, ereport, errcode(), errmsg(), ERROR, FATAL, INIT_PG_OVERRIDE_ALLOW_CONNS, INIT_PG_OVERRIDE_ROLE_LOGIN, InitPostgres(), InvalidOid, IsInitProcessingMode, MyBgworkerEntry, NormalProcessing, SetProcessingMode, and username.

Referenced by ApplyLauncherMain(), and worker_spi_main().

◆ BackgroundWorkerInitializeConnectionByOid()

void BackgroundWorkerInitializeConnectionByOid ( Oid  dboid,
Oid  useroid,
uint32  flags 
)

Definition at line 886 of file bgworker.c.

887{
889 bits32 init_flags = 0; /* never honor session_preload_libraries */
890
891 /* ignore datallowconn and ACL_CONNECT? */
892 if (flags & BGWORKER_BYPASS_ALLOWCONN)
893 init_flags |= INIT_PG_OVERRIDE_ALLOW_CONNS;
894 /* ignore rolcanlogin? */
896 init_flags |= INIT_PG_OVERRIDE_ROLE_LOGIN;
897
898 /* XXX is this the right errcode? */
901 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
902 errmsg("database connection requirement not indicated during registration")));
903
904 InitPostgres(NULL, dboid, /* database to connect to */
905 NULL, useroid, /* role to connect as */
906 init_flags,
907 NULL); /* no out_dbname */
908
909 /* it had better not gotten out of "init" mode yet */
912 (errmsg("invalid processing mode in background worker")));
914}

References BackgroundWorker::bgw_flags, BGWORKER_BACKEND_DATABASE_CONNECTION, BGWORKER_BYPASS_ALLOWCONN, BGWORKER_BYPASS_ROLELOGINCHECK, ereport, errcode(), errmsg(), ERROR, FATAL, INIT_PG_OVERRIDE_ALLOW_CONNS, INIT_PG_OVERRIDE_ROLE_LOGIN, InitPostgres(), IsInitProcessingMode, MyBgworkerEntry, NormalProcessing, and SetProcessingMode.

Referenced by autoprewarm_database_main(), InitializeLogRepWorker(), ParallelWorkerMain(), and worker_spi_main().

◆ BackgroundWorkerUnblockSignals()

void BackgroundWorkerUnblockSignals ( void  )

◆ GetBackgroundWorkerPid()

BgwHandleStatus GetBackgroundWorkerPid ( BackgroundWorkerHandle handle,
pid_t *  pidp 
)

Definition at line 1157 of file bgworker.c.

1158{
1160 pid_t pid;
1161
1162 Assert(handle->slot < max_worker_processes);
1163 slot = &BackgroundWorkerData->slot[handle->slot];
1164
1165 /*
1166 * We could probably arrange to synchronize access to data using memory
1167 * barriers only, but for now, let's just keep it simple and grab the
1168 * lock. It seems unlikely that there will be enough traffic here to
1169 * result in meaningful contention.
1170 */
1171 LWLockAcquire(BackgroundWorkerLock, LW_SHARED);
1172
1173 /*
1174 * The generation number can't be concurrently changed while we hold the
1175 * lock. The pid, which is updated by the postmaster, can change at any
1176 * time, but we assume such changes are atomic. So the value we read
1177 * won't be garbage, but it might be out of date by the time the caller
1178 * examines it (but that's unavoidable anyway).
1179 *
1180 * The in_use flag could be in the process of changing from true to false,
1181 * but if it is already false then it can't change further.
1182 */
1183 if (handle->generation != slot->generation || !slot->in_use)
1184 pid = 0;
1185 else
1186 pid = slot->pid;
1187
1188 /* All done. */
1189 LWLockRelease(BackgroundWorkerLock);
1190
1191 if (pid == 0)
1192 return BGWH_STOPPED;
1193 else if (pid == InvalidPid)
1194 return BGWH_NOT_YET_STARTED;
1195 *pidp = pid;
1196 return BGWH_STARTED;
1197}
static BackgroundWorkerArray * BackgroundWorkerData
Definition: bgworker.c:108
int max_worker_processes
Definition: globals.c:145
Assert(PointerIsAligned(start, uint64))
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1182
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1902
@ LW_SHARED
Definition: lwlock.h:115
#define InvalidPid
Definition: miscadmin.h:32
BackgroundWorkerSlot slot[FLEXIBLE_ARRAY_MEMBER]
Definition: bgworker.c:99

References Assert(), BackgroundWorkerData, BGWH_NOT_YET_STARTED, BGWH_STARTED, BGWH_STOPPED, BackgroundWorkerSlot::generation, BackgroundWorkerHandle::generation, BackgroundWorkerSlot::in_use, InvalidPid, LW_SHARED, LWLockAcquire(), LWLockRelease(), max_worker_processes, BackgroundWorkerSlot::pid, BackgroundWorkerArray::slot, and BackgroundWorkerHandle::slot.

Referenced by check_worker_status(), shm_mq_counterparty_gone(), shm_mq_wait_internal(), WaitForBackgroundWorkerShutdown(), WaitForBackgroundWorkerStartup(), WaitForParallelWorkersToAttach(), WaitForParallelWorkersToFinish(), and WaitForReplicationWorkerAttach().

◆ GetBackgroundWorkerTypeByPid()

const char * GetBackgroundWorkerTypeByPid ( pid_t  pid)

Definition at line 1371 of file bgworker.c.

1372{
1373 int slotno;
1374 bool found = false;
1375 static char result[BGW_MAXLEN];
1376
1377 LWLockAcquire(BackgroundWorkerLock, LW_SHARED);
1378
1379 for (slotno = 0; slotno < BackgroundWorkerData->total_slots; slotno++)
1380 {
1382
1383 if (slot->pid > 0 && slot->pid == pid)
1384 {
1385 strcpy(result, slot->worker.bgw_type);
1386 found = true;
1387 break;
1388 }
1389 }
1390
1391 LWLockRelease(BackgroundWorkerLock);
1392
1393 if (!found)
1394 return NULL;
1395
1396 return result;
1397}
#define BGW_MAXLEN
Definition: bgworker.h:86
BackgroundWorker worker
Definition: bgworker.c:80
char bgw_type[BGW_MAXLEN]
Definition: bgworker.h:92

References BackgroundWorkerData, BGW_MAXLEN, BackgroundWorker::bgw_type, LW_SHARED, LWLockAcquire(), LWLockRelease(), BackgroundWorkerSlot::pid, BackgroundWorkerArray::slot, BackgroundWorkerArray::total_slots, and BackgroundWorkerSlot::worker.

Referenced by pg_stat_get_activity().

◆ RegisterBackgroundWorker()

void RegisterBackgroundWorker ( BackgroundWorker worker)

Definition at line 939 of file bgworker.c.

940{
942 static int numworkers = 0;
943
944 /*
945 * Static background workers can only be registered in the postmaster
946 * process.
947 */
949 {
950 /*
951 * In EXEC_BACKEND or single-user mode, we process
952 * shared_preload_libraries in backend processes too. We cannot
953 * register static background workers at that stage, but many
954 * libraries' _PG_init() functions don't distinguish whether they're
955 * being loaded in the postmaster or in a backend, they just check
956 * process_shared_preload_libraries_in_progress. It's a bit sloppy,
957 * but for historical reasons we tolerate it. In EXEC_BACKEND mode,
958 * the background workers should already have been registered when the
959 * library was loaded in postmaster.
960 */
962 return;
963 ereport(LOG,
964 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
965 errmsg("background worker \"%s\": must be registered in \"shared_preload_libraries\"",
966 worker->bgw_name)));
967 return;
968 }
969
970 /*
971 * Cannot register static background workers after calling
972 * BackgroundWorkerShmemInit().
973 */
974 if (BackgroundWorkerData != NULL)
975 elog(ERROR, "cannot register background worker \"%s\" after shmem init",
976 worker->bgw_name);
977
979 (errmsg_internal("registering background worker \"%s\"", worker->bgw_name)));
980
981 if (!SanityCheckBackgroundWorker(worker, LOG))
982 return;
983
984 if (worker->bgw_notify_pid != 0)
985 {
986 ereport(LOG,
987 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
988 errmsg("background worker \"%s\": only dynamic background workers can request notification",
989 worker->bgw_name)));
990 return;
991 }
992
993 /*
994 * Enforce maximum number of workers. Note this is overly restrictive: we
995 * could allow more non-shmem-connected workers, because these don't count
996 * towards the MAX_BACKENDS limit elsewhere. For now, it doesn't seem
997 * important to relax this restriction.
998 */
999 if (++numworkers > max_worker_processes)
1000 {
1001 ereport(LOG,
1002 (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
1003 errmsg("too many background workers"),
1004 errdetail_plural("Up to %d background worker can be registered with the current settings.",
1005 "Up to %d background workers can be registered with the current settings.",
1008 errhint("Consider increasing the configuration parameter \"%s\".", "max_worker_processes")));
1009 return;
1010 }
1011
1012 /*
1013 * Copy the registration data into the registered workers list.
1014 */
1016 sizeof(RegisteredBgWorker),
1018 if (rw == NULL)
1019 {
1020 ereport(LOG,
1021 (errcode(ERRCODE_OUT_OF_MEMORY),
1022 errmsg("out of memory")));
1023 return;
1024 }
1025
1026 rw->rw_worker = *worker;
1027 rw->rw_pid = 0;
1028 rw->rw_crashed_at = 0;
1029 rw->rw_terminate = false;
1030
1032}
static bool SanityCheckBackgroundWorker(BackgroundWorker *worker, int elevel)
Definition: bgworker.c:631
dlist_head BackgroundWorkerList
Definition: bgworker.c:40
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1158
int errdetail_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:1296
int errhint(const char *fmt,...)
Definition: elog.c:1318
#define LOG
Definition: elog.h:31
#define DEBUG1
Definition: elog.h:30
#define elog(elevel,...)
Definition: elog.h:226
#define MCXT_ALLOC_NO_OOM
Definition: fe_memutils.h:29
bool IsUnderPostmaster
Definition: globals.c:121
bool IsPostmasterEnvironment
Definition: globals.c:120
static void dlist_push_head(dlist_head *head, dlist_node *node)
Definition: ilist.h:347
void * MemoryContextAllocExtended(MemoryContext context, Size size, int flags)
Definition: mcxt.c:1313
MemoryContext PostmasterContext
Definition: mcxt.c:167
bool process_shared_preload_libraries_in_progress
Definition: miscinit.c:1837
char bgw_name[BGW_MAXLEN]
Definition: bgworker.h:91
pid_t bgw_notify_pid
Definition: bgworker.h:100
BackgroundWorker rw_worker

References BackgroundWorkerData, BackgroundWorkerList, BackgroundWorker::bgw_name, BackgroundWorker::bgw_notify_pid, DEBUG1, dlist_push_head(), elog, ereport, errcode(), errdetail_plural(), errhint(), errmsg(), errmsg_internal(), ERROR, IsPostmasterEnvironment, IsUnderPostmaster, LOG, max_worker_processes, MCXT_ALLOC_NO_OOM, MemoryContextAllocExtended(), PostmasterContext, process_shared_preload_libraries_in_progress, RegisteredBgWorker::rw_crashed_at, RegisteredBgWorker::rw_lnode, RegisteredBgWorker::rw_pid, RegisteredBgWorker::rw_terminate, RegisteredBgWorker::rw_worker, and SanityCheckBackgroundWorker().

Referenced by _PG_init(), ApplyLauncherRegister(), and apw_start_leader_worker().

◆ RegisterDynamicBackgroundWorker()

bool RegisterDynamicBackgroundWorker ( BackgroundWorker worker,
BackgroundWorkerHandle **  handle 
)

Definition at line 1045 of file bgworker.c.

1047{
1048 int slotno;
1049 bool success = false;
1050 bool parallel;
1051 uint64 generation = 0;
1052
1053 /*
1054 * We can't register dynamic background workers from the postmaster. If
1055 * this is a standalone backend, we're the only process and can't start
1056 * any more. In a multi-process environment, it might be theoretically
1057 * possible, but we don't currently support it due to locking
1058 * considerations; see comments on the BackgroundWorkerSlot data
1059 * structure.
1060 */
1061 if (!IsUnderPostmaster)
1062 return false;
1063
1064 if (!SanityCheckBackgroundWorker(worker, ERROR))
1065 return false;
1066
1067 parallel = (worker->bgw_flags & BGWORKER_CLASS_PARALLEL) != 0;
1068
1069 LWLockAcquire(BackgroundWorkerLock, LW_EXCLUSIVE);
1070
1071 /*
1072 * If this is a parallel worker, check whether there are already too many
1073 * parallel workers; if so, don't register another one. Our view of
1074 * parallel_terminate_count may be slightly stale, but that doesn't really
1075 * matter: we would have gotten the same result if we'd arrived here
1076 * slightly earlier anyway. There's no help for it, either, since the
1077 * postmaster must not take locks; a memory barrier wouldn't guarantee
1078 * anything useful.
1079 */
1083 {
1087 LWLockRelease(BackgroundWorkerLock);
1088 return false;
1089 }
1090
1091 /*
1092 * Look for an unused slot. If we find one, grab it.
1093 */
1094 for (slotno = 0; slotno < BackgroundWorkerData->total_slots; ++slotno)
1095 {
1097
1098 if (!slot->in_use)
1099 {
1100 memcpy(&slot->worker, worker, sizeof(BackgroundWorker));
1101 slot->pid = InvalidPid; /* indicates not started yet */
1102 slot->generation++;
1103 slot->terminate = false;
1104 generation = slot->generation;
1105 if (parallel)
1107
1108 /*
1109 * Make sure postmaster doesn't see the slot as in use before it
1110 * sees the new contents.
1111 */
1113
1114 slot->in_use = true;
1115 success = true;
1116 break;
1117 }
1118 }
1119
1120 LWLockRelease(BackgroundWorkerLock);
1121
1122 /* If we found a slot, tell the postmaster to notice the change. */
1123 if (success)
1125
1126 /*
1127 * If we found a slot and the user has provided a handle, initialize it.
1128 */
1129 if (success && handle)
1130 {
1131 *handle = palloc(sizeof(BackgroundWorkerHandle));
1132 (*handle)->slot = slotno;
1133 (*handle)->generation = generation;
1134 }
1135
1136 return success;
1137}
#define pg_write_barrier()
Definition: atomics.h:157
#define BGWORKER_CLASS_PARALLEL
Definition: bgworker.h:68
#define MAX_PARALLEL_WORKER_LIMIT
uint64_t uint64
Definition: c.h:503
int max_parallel_workers
Definition: globals.c:146
static bool success
Definition: initdb.c:187
@ LW_EXCLUSIVE
Definition: lwlock.h:114
void * palloc(Size size)
Definition: mcxt.c:1939
void SendPostmasterSignal(PMSignalReason reason)
Definition: pmsignal.c:165
@ PMSIGNAL_BACKGROUND_WORKER_CHANGE
Definition: pmsignal.h:41
uint32 parallel_terminate_count
Definition: bgworker.c:98
uint32 parallel_register_count
Definition: bgworker.c:97

References Assert(), BackgroundWorkerData, BackgroundWorker::bgw_flags, BGWORKER_CLASS_PARALLEL, ERROR, BackgroundWorkerSlot::generation, BackgroundWorkerSlot::in_use, InvalidPid, IsUnderPostmaster, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MAX_PARALLEL_WORKER_LIMIT, max_parallel_workers, palloc(), BackgroundWorkerArray::parallel_register_count, BackgroundWorkerArray::parallel_terminate_count, pg_write_barrier, BackgroundWorkerSlot::pid, PMSIGNAL_BACKGROUND_WORKER_CHANGE, SanityCheckBackgroundWorker(), SendPostmasterSignal(), BackgroundWorkerArray::slot, success, BackgroundWorkerSlot::terminate, BackgroundWorkerArray::total_slots, and BackgroundWorkerSlot::worker.

Referenced by apw_start_database_worker(), apw_start_leader_worker(), LaunchParallelWorkers(), logicalrep_worker_launch(), setup_background_workers(), and worker_spi_launch().

◆ TerminateBackgroundWorker()

void TerminateBackgroundWorker ( BackgroundWorkerHandle handle)

Definition at line 1296 of file bgworker.c.

1297{
1299 bool signal_postmaster = false;
1300
1301 Assert(handle->slot < max_worker_processes);
1302 slot = &BackgroundWorkerData->slot[handle->slot];
1303
1304 /* Set terminate flag in shared memory, unless slot has been reused. */
1305 LWLockAcquire(BackgroundWorkerLock, LW_EXCLUSIVE);
1306 if (handle->generation == slot->generation)
1307 {
1308 slot->terminate = true;
1309 signal_postmaster = true;
1310 }
1311 LWLockRelease(BackgroundWorkerLock);
1312
1313 /* Make sure the postmaster notices the change to shared memory. */
1314 if (signal_postmaster)
1316}

References Assert(), BackgroundWorkerData, BackgroundWorkerSlot::generation, BackgroundWorkerHandle::generation, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), max_worker_processes, PMSIGNAL_BACKGROUND_WORKER_CHANGE, SendPostmasterSignal(), BackgroundWorkerArray::slot, BackgroundWorkerHandle::slot, and BackgroundWorkerSlot::terminate.

Referenced by cleanup_background_workers(), and DestroyParallelContext().

◆ WaitForBackgroundWorkerShutdown()

BgwHandleStatus WaitForBackgroundWorkerShutdown ( BackgroundWorkerHandle handle)

Definition at line 1257 of file bgworker.c.

1258{
1259 BgwHandleStatus status;
1260 int rc;
1261
1262 for (;;)
1263 {
1264 pid_t pid;
1265
1267
1268 status = GetBackgroundWorkerPid(handle, &pid);
1269 if (status == BGWH_STOPPED)
1270 break;
1271
1272 rc = WaitLatch(MyLatch,
1274 WAIT_EVENT_BGWORKER_SHUTDOWN);
1275
1276 if (rc & WL_POSTMASTER_DEATH)
1277 {
1278 status = BGWH_POSTMASTER_DIED;
1279 break;
1280 }
1281
1283 }
1284
1285 return status;
1286}
BgwHandleStatus GetBackgroundWorkerPid(BackgroundWorkerHandle *handle, pid_t *pidp)
Definition: bgworker.c:1157
struct Latch * MyLatch
Definition: globals.c:64
void ResetLatch(Latch *latch)
Definition: latch.c:372
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:172
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:123
#define WL_LATCH_SET
Definition: waiteventset.h:34
#define WL_POSTMASTER_DEATH
Definition: waiteventset.h:38

References BGWH_POSTMASTER_DIED, BGWH_STOPPED, CHECK_FOR_INTERRUPTS, GetBackgroundWorkerPid(), MyLatch, ResetLatch(), WaitLatch(), WL_LATCH_SET, and WL_POSTMASTER_DEATH.

Referenced by apw_start_database_worker(), and WaitForParallelWorkersToExit().

◆ WaitForBackgroundWorkerStartup()

BgwHandleStatus WaitForBackgroundWorkerStartup ( BackgroundWorkerHandle handle,
pid_t *  pidp 
)

Definition at line 1212 of file bgworker.c.

1213{
1214 BgwHandleStatus status;
1215 int rc;
1216
1217 for (;;)
1218 {
1219 pid_t pid;
1220
1222
1223 status = GetBackgroundWorkerPid(handle, &pid);
1224 if (status == BGWH_STARTED)
1225 *pidp = pid;
1226 if (status != BGWH_NOT_YET_STARTED)
1227 break;
1228
1229 rc = WaitLatch(MyLatch,
1231 WAIT_EVENT_BGWORKER_STARTUP);
1232
1233 if (rc & WL_POSTMASTER_DEATH)
1234 {
1235 status = BGWH_POSTMASTER_DIED;
1236 break;
1237 }
1238
1240 }
1241
1242 return status;
1243}

References BGWH_NOT_YET_STARTED, BGWH_POSTMASTER_DIED, BGWH_STARTED, CHECK_FOR_INTERRUPTS, GetBackgroundWorkerPid(), MyLatch, ResetLatch(), WaitLatch(), WL_LATCH_SET, and WL_POSTMASTER_DEATH.

Referenced by apw_start_leader_worker(), and worker_spi_launch().

Variable Documentation

◆ MyBgworkerEntry