1 /*-------------------------------------------------------------------- 2 * bgworker.h 3 * POSTGRES pluggable background workers interface 4 * 5 * A background worker is a process able to run arbitrary, user-supplied code, 6 * including normal transactions. 7 * 8 * Any external module loaded via shared_preload_libraries can register a 9 * worker. Workers can also be registered dynamically at runtime. In either 10 * case, the worker process is forked from the postmaster and runs the 11 * user-supplied "main" function. This code may connect to a database and 12 * run transactions. Workers can remain active indefinitely, but will be 13 * terminated if a shutdown or crash occurs. 14 * 15 * If the fork() call fails in the postmaster, it will try again later. Note 16 * that the failure can only be transient (fork failure due to high load, 17 * memory pressure, too many processes, etc); more permanent problems, like 18 * failure to connect to a database, are detected later in the worker and dealt 19 * with just by having the worker exit normally. A worker which exits with 20 * a return code of 0 will never be restarted and will be removed from worker 21 * list. A worker which exits with a return code of 1 will be restarted after 22 * the configured restart interval (unless that interval is BGW_NEVER_RESTART). 23 * The TerminateBackgroundWorker() function can be used to terminate a 24 * dynamically registered background worker; the worker will be sent a SIGTERM 25 * and will not be restarted after it exits. Whenever the postmaster knows 26 * that a worker will not be restarted, it unregisters the worker, freeing up 27 * that worker's slot for use by a new worker. 28 * 29 * Note that there might be more than one worker in a database concurrently, 30 * and the same module may request more than one worker running the same (or 31 * different) code. 32 * 33 * 34 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group 35 * Portions Copyright (c) 1994, Regents of the University of California 36 * 37 * IDENTIFICATION 38 * src/include/postmaster/bgworker.h 39 *-------------------------------------------------------------------- 40 */ 41 #ifndef BGWORKER_H 42 #define BGWORKER_H 43 44 /*--------------------------------------------------------------------- 45 * External module API. 46 *--------------------------------------------------------------------- 47 */ 48 49 /* 50 * Pass this flag to have your worker be able to connect to shared memory. 51 */ 52 #define BGWORKER_SHMEM_ACCESS 0x0001 53 54 /* 55 * This flag means the bgworker requires a database connection. The connection 56 * is not established automatically; the worker must establish it later. 57 * It requires that BGWORKER_SHMEM_ACCESS was passed too. 58 */ 59 #define BGWORKER_BACKEND_DATABASE_CONNECTION 0x0002 60 61 /* 62 * This class is used internally for parallel queries, to keep track of the 63 * number of active parallel workers and make sure we never launch more than 64 * max_parallel_workers parallel workers at the same time. Third party 65 * background workers should not use this class. 66 */ 67 #define BGWORKER_CLASS_PARALLEL 0x0010 68 /* add additional bgworker classes here */ 69 70 71 typedef void (*bgworker_main_type) (Datum main_arg); 72 73 /* 74 * Points in time at which a bgworker can request to be started 75 */ 76 typedef enum 77 { 78 BgWorkerStart_PostmasterStart, 79 BgWorkerStart_ConsistentState, 80 BgWorkerStart_RecoveryFinished 81 } BgWorkerStartTime; 82 83 #define BGW_DEFAULT_RESTART_INTERVAL 60 84 #define BGW_NEVER_RESTART -1 85 #define BGW_MAXLEN 64 86 #define BGW_EXTRALEN 128 87 88 typedef struct BackgroundWorker 89 { 90 char bgw_name[BGW_MAXLEN]; 91 int bgw_flags; 92 BgWorkerStartTime bgw_start_time; 93 int bgw_restart_time; /* in seconds, or BGW_NEVER_RESTART */ 94 char bgw_library_name[BGW_MAXLEN]; 95 char bgw_function_name[BGW_MAXLEN]; 96 Datum bgw_main_arg; 97 char bgw_extra[BGW_EXTRALEN]; 98 pid_t bgw_notify_pid; /* SIGUSR1 this backend on start/stop */ 99 } BackgroundWorker; 100 101 typedef enum BgwHandleStatus 102 { 103 BGWH_STARTED, /* worker is running */ 104 BGWH_NOT_YET_STARTED, /* worker hasn't been started yet */ 105 BGWH_STOPPED, /* worker has exited */ 106 BGWH_POSTMASTER_DIED /* postmaster died; worker status unclear */ 107 } BgwHandleStatus; 108 109 struct BackgroundWorkerHandle; 110 typedef struct BackgroundWorkerHandle BackgroundWorkerHandle; 111 112 /* Register a new bgworker during shared_preload_libraries */ 113 extern void RegisterBackgroundWorker(BackgroundWorker *worker); 114 115 /* Register a new bgworker from a regular backend */ 116 extern bool RegisterDynamicBackgroundWorker(BackgroundWorker *worker, 117 BackgroundWorkerHandle **handle); 118 119 /* Query the status of a bgworker */ 120 extern BgwHandleStatus GetBackgroundWorkerPid(BackgroundWorkerHandle *handle, 121 pid_t *pidp); 122 extern BgwHandleStatus WaitForBackgroundWorkerStartup(BackgroundWorkerHandle *handle, pid_t *pid); 123 extern BgwHandleStatus 124 WaitForBackgroundWorkerShutdown(BackgroundWorkerHandle *); 125 126 /* Terminate a bgworker */ 127 extern void TerminateBackgroundWorker(BackgroundWorkerHandle *handle); 128 129 /* This is valid in a running worker */ 130 extern PGDLLIMPORT BackgroundWorker *MyBgworkerEntry; 131 132 /* 133 * Connect to the specified database, as the specified user. Only a worker 134 * that passed BGWORKER_BACKEND_DATABASE_CONNECTION during registration may 135 * call this. 136 * 137 * If username is NULL, bootstrapping superuser is used. 138 * If dbname is NULL, connection is made to no specific database; 139 * only shared catalogs can be accessed. 140 */ 141 extern void BackgroundWorkerInitializeConnection(char *dbname, char *username); 142 143 /* Just like the above, but specifying database and user by OID. */ 144 extern void BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid); 145 146 /* Block/unblock signals in a background worker process */ 147 extern void BackgroundWorkerBlockSignals(void); 148 extern void BackgroundWorkerUnblockSignals(void); 149 150 #endif /* BGWORKER_H */ 151