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 72 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? */
858  if (flags & BGWORKER_BYPASS_ALLOWCONN)
859  init_flags |= INIT_PG_OVERRIDE_ALLOW_CONNS;
860  /* ignore rolcanlogin? */
861  if (flags & BGWORKER_BYPASS_ROLELOGINCHECK)
862  init_flags |= INIT_PG_OVERRIDE_ROLE_LOGIN;
863 
864  /* XXX is this the right errcode? */
866  ereport(FATAL,
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 */
876  if (!IsInitProcessingMode())
877  ereport(ERROR,
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:500
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#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:449
#define IsInitProcessingMode()
Definition: miscadmin.h:455
#define SetProcessingMode(mode)
Definition: miscadmin.h:460
#define INIT_PG_OVERRIDE_ROLE_LOGIN
Definition: miscadmin.h:478
#define INIT_PG_OVERRIDE_ALLOW_CONNS
Definition: miscadmin.h:477
#define InvalidOid
Definition: postgres_ext.h:36
void InitPostgres(const char *in_dbname, Oid dboid, const char *username, Oid useroid, bits32 flags, char *out_dbname)
Definition: postinit.c:698
BackgroundWorker * MyBgworkerEntry
Definition: postmaster.c:192
char * dbname
Definition: streamutil.c:50

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? */
892  if (flags & BGWORKER_BYPASS_ALLOWCONN)
893  init_flags |= INIT_PG_OVERRIDE_ALLOW_CONNS;
894  /* ignore rolcanlogin? */
895  if (flags & BGWORKER_BYPASS_ROLELOGINCHECK)
896  init_flags |= INIT_PG_OVERRIDE_ROLE_LOGIN;
897 
898  /* XXX is this the right errcode? */
900  ereport(FATAL,
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 */
910  if (!IsInitProcessingMode())
911  ereport(ERROR,
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  )

Definition at line 926 of file bgworker.c.

927 {
928  sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
929 }
sigset_t UnBlockSig
Definition: pqsignal.c:22

References UnBlockSig.

Referenced by ApplyLauncherMain(), autoprewarm_database_main(), autoprewarm_main(), BackgroundWorkerMain(), ParallelApplyWorkerMain(), ParallelWorkerMain(), SetupApplyOrSyncWorker(), test_shm_mq_main(), and worker_spi_main().

◆ GetBackgroundWorkerPid()

BgwHandleStatus GetBackgroundWorkerPid ( BackgroundWorkerHandle handle,
pid_t *  pidp 
)

Definition at line 1157 of file bgworker.c.

1158 {
1159  BackgroundWorkerSlot *slot;
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
#define Assert(condition)
Definition: c.h:837
int max_worker_processes
Definition: globals.c:143
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1168
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1781
@ 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 {
941  RegisteredBgWorker *rw;
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 
978  ereport(DEBUG1,
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:1157
int errdetail_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:1295
int errhint(const char *fmt,...)
Definition: elog.c:1317
#define LOG
Definition: elog.h:31
#define DEBUG1
Definition: elog.h:30
#define elog(elevel,...)
Definition: elog.h:225
#define MCXT_ALLOC_NO_OOM
Definition: fe_memutils.h:29
bool IsUnderPostmaster
Definition: globals.c:119
bool IsPostmasterEnvironment
Definition: globals.c:118
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:1238
MemoryContext PostmasterContext
Definition: mcxt.c:151
bool process_shared_preload_libraries_in_progress
Definition: miscinit.c:1839
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  */
1080  if (parallel && (BackgroundWorkerData->parallel_register_count -
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  */
1112  pg_write_barrier();
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
int max_parallel_workers
Definition: globals.c:144
static bool success
Definition: initdb.c:186
@ LW_EXCLUSIVE
Definition: lwlock.h:114
void * palloc(Size size)
Definition: mcxt.c:1317
void SendPostmasterSignal(PMSignalReason reason)
Definition: pmsignal.c:165
@ PMSIGNAL_BACKGROUND_WORKER_CHANGE
Definition: pmsignal.h:40
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 {
1298  BackgroundWorkerSlot *slot;
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:62
void ResetLatch(Latch *latch)
Definition: latch.c:724
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:517
#define WL_LATCH_SET
Definition: latch.h:127
#define WL_POSTMASTER_DEATH
Definition: latch.h:131
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122

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