text: /*--------------------------------------------------------------------
   * bgworker.h
   *		POSTGRES pluggable background workers interface
   *
   * A background worker is a process able to run arbitrary, user-supplied code,
   * including normal transactions.
   *
   * Any external module loaded via shared_preload_libraries can register a
   * worker.  Workers can also be registered dynamically at runtime.  In either
   * case, the worker process is forked from the postmaster and runs the
   * user-supplied "main" function.  This code may connect to a database and
   * run transactions.  Workers can remain active indefinitely, but will be
   * terminated if a shutdown or crash occurs.
   *
   * If the fork() call fails in the postmaster, it will try again later.  Note
   * that the failure can only be transient (fork failure due to high load,
   * memory pressure, too many processes, etc); more permanent problems, like
   * failure to connect to a database, are detected later in the worker and dealt
   * with just by having the worker exit normally. A worker which exits with
   * a return code of 0 will never be restarted and will be removed from worker
   * list. A worker which exits with a return code of 1 will be restarted after
   * the configured restart interval (unless that interval is BGW_NEVER_RESTART).
   * The TerminateBackgroundWorker() function can be used to terminate a
   * dynamically registered background worker; the worker will be sent a SIGTERM
   * and will not be restarted after it exits.  Whenever the postmaster knows
   * that a worker will not be restarted, it unregisters the worker, freeing up
   * that worker's slot for use by a new worker.
   *
   * Note that there might be more than one worker in a database concurrently,
   * and the same module may request more than one worker running the same (or
   * different) code.
   *
   *
   * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
   * Portions Copyright (c) 1994, Regents of the University of California
   *
   * IDENTIFICATION
   *		src/include/postmaster/bgworker.h
   *--------------------------------------------------------------------
   */
  #ifndef BGWORKER_H
  #define BGWORKER_H
  
  /*---------------------------------------------------------------------
   * External module API.
   *---------------------------------------------------------------------
   */
  
  /*
   * Pass this flag to have your worker be able to connect to shared memory.
   */
  #define BGWORKER_SHMEM_ACCESS						0x0001
  
  /*
   * This flag means the bgworker requires a database connection.  The connection
   * is not established automatically; the worker must establish it later.
   * It requires that BGWORKER_SHMEM_ACCESS was passed too.
   */
  #define BGWORKER_BACKEND_DATABASE_CONNECTION		0x0002
  
  
  typedef void (*bgworker_main_type) (Datum main_arg);
  
  /*
   * Points in time at which a bgworker can request to be started
   */
  typedef enum
  {
  	BgWorkerStart_PostmasterStart,
  	BgWorkerStart_ConsistentState,
  	BgWorkerStart_RecoveryFinished
  } BgWorkerStartTime;
  
  #define BGW_DEFAULT_RESTART_INTERVAL	60
  #define BGW_NEVER_RESTART				-1
  #define BGW_MAXLEN						64
  
  typedef struct BackgroundWorker
  {
  	char		bgw_name[BGW_MAXLEN];
  	int			bgw_flags;
  	BgWorkerStartTime bgw_start_time;
  	int			bgw_restart_time;		/* in seconds, or BGW_NEVER_RESTART */
  	bgworker_main_type bgw_main;
  	char		bgw_library_name[BGW_MAXLEN];	/* only if bgw_main is NULL */
  	char		bgw_function_name[BGW_MAXLEN];	/* only if bgw_main is NULL */
  	Datum		bgw_main_arg;
  	pid_t		bgw_notify_pid; /* SIGUSR1 this backend on start/stop */
  } BackgroundWorker;
  
  typedef enum BgwHandleStatus
  {
  	BGWH_STARTED,				/* worker is running */
  	BGWH_NOT_YET_STARTED,		/* worker hasn't been started yet */
  	BGWH_STOPPED,				/* worker has exited */
  	BGWH_POSTMASTER_DIED		/* postmaster died; worker status unclear */
  } BgwHandleStatus;
  
  struct BackgroundWorkerHandle;
  typedef struct BackgroundWorkerHandle BackgroundWorkerHandle;
  
  /* Register a new bgworker during shared_preload_libraries */
  extern void RegisterBackgroundWorker(BackgroundWorker *worker);
  
  /* Register a new bgworker from a regular backend */
  extern bool RegisterDynamicBackgroundWorker(BackgroundWorker *worker,
  								BackgroundWorkerHandle **handle);
  
  /* Query the status of a bgworker */
  extern BgwHandleStatus GetBackgroundWorkerPid(BackgroundWorkerHandle *handle,
  					   pid_t *pidp);
  extern BgwHandleStatus
  WaitForBackgroundWorkerStartup(BackgroundWorkerHandle *
  							   handle, pid_t *pid);
  
  /* Terminate a bgworker */
  extern void TerminateBackgroundWorker(BackgroundWorkerHandle *handle);
  
  /* This is valid in a running worker */
  extern PGDLLIMPORT BackgroundWorker *MyBgworkerEntry;
  
  /*
   * Connect to the specified database, as the specified user.  Only a worker
   * that passed BGWORKER_BACKEND_DATABASE_CONNECTION during registration may
   * call this.
   *
   * If username is NULL, bootstrapping superuser is used.
   * If dbname is NULL, connection is made to no specific database;
   * only shared catalogs can be accessed.
   */
  extern void BackgroundWorkerInitializeConnection(char *dbname, char *username);
  
  /* Just like the above, but specifying database and user by OID. */
  extern void BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid);
  
  /* Block/unblock signals in a background worker process */
  extern void BackgroundWorkerBlockSignals(void);
  extern void BackgroundWorkerUnblockSignals(void);
  
  #endif   /* BGWORKER_H */
  