Flesh out the background worker documentation.

Make it more clear that bgw_main is usually not what you want.  Put the
background worker flags in a variablelist rather than having them as
part of a paragraph.  Explain important limits on how bgw_main_arg can
be used.

Craig Ringer, substantially revised by me.
This commit is contained in:
Robert Haas 2015-07-29 14:41:07 -04:00
parent c7f0b28c7a
commit 38d4ce6b05
1 changed files with 72 additions and 26 deletions

View File

@ -70,14 +70,39 @@ typedef struct BackgroundWorker
<para> <para>
<structfield>bgw_flags</> is a bitwise-or'd bit mask indicating the <structfield>bgw_flags</> is a bitwise-or'd bit mask indicating the
capabilities that the module wants. Possible values are capabilities that the module wants. Possible values are:
<literal>BGWORKER_SHMEM_ACCESS</literal> (requesting shared memory access) <variablelist>
and <literal>BGWORKER_BACKEND_DATABASE_CONNECTION</literal> (requesting the
ability to establish a database connection, through which it can later run <varlistentry>
transactions and queries). A background worker using <term><literal>BGWORKER_SHMEM_ACCESS</literal></term>
<literal>BGWORKER_BACKEND_DATABASE_CONNECTION</literal> to connect to <listitem>
a database must also attach shared memory using <para>
<literal>BGWORKER_SHMEM_ACCESS</literal>, or worker start-up will fail. <indexterm><primary>BGWORKER_SHMEM_ACCESS</primary></indexterm>
Requests shared memory access. Workers without shared memory access
cannot access any of <productname>PostgreSQL's</productname> shared
data structures, such as heavyweight or lightweight locks, shared
buffers, or any custom data structures which the worker itself may
wish to create and use.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>BGWORKER_BACKEND_DATABASE_CONNECTION</literal></term>
<listitem>
<para>
<indexterm><primary>BGWORKER_BACKEND_DATABASE_CONNECTION</primary></indexterm>
Requests the ability to establish a database connection through which it
can later run transactions and queries. A background worker using
<literal>BGWORKER_BACKEND_DATABASE_CONNECTION</literal> to connect to a
database must also attach shared memory using
<literal>BGWORKER_SHMEM_ACCESS</literal>, or worker start-up will fail.
</para>
</listitem>
</varlistentry>
</variablelist>
</para> </para>
<para> <para>
@ -106,34 +131,55 @@ typedef struct BackgroundWorker
<para> <para>
<structfield>bgw_main</structfield> is a pointer to the function to run when <structfield>bgw_main</structfield> is a pointer to the function to run when
the process is started. This function must take a single argument of type the process is started. This field can only safely be used to launch
<type>Datum</> and return <type>void</>. functions within the core server, because shared libraries may be loaded
<structfield>bgw_main_arg</structfield> will be passed to it as its only at different starting addresses in different backend processes. This will
argument. Note that the global variable <literal>MyBgworkerEntry</literal> happen on all platforms when the library is loaded using any mechanism
points to a copy of the <structname>BackgroundWorker</structname> structure other than <xref linkend="guc-shared-preload-libraries">. Even when that
passed at registration time. <structfield>bgw_main</structfield> may be mechanism is used, address space layout variations will still occur on
NULL; in that case, <structfield>bgw_library_name</structfield> and Windows, and when <literal>EXEC_BACKEND</> is used. Therefore, most users
<structfield>bgw_function_name</structfield> will be used to determine of this API should set this field to NULL. If it is non-NULL, it takes
the entry point. This is useful for background workers launched after precedence over <structfield>bgw_library_name</> and
postmaster startup, where the postmaster does not have the requisite <structfield>bgw_function_name</>.
library loaded.
</para> </para>
<para> <para>
<structfield>bgw_library_name</structfield> is the name of a library in <structfield>bgw_library_name</structfield> is the name of a library in
which the initial entry point for the background worker should be sought. which the initial entry point for the background worker should be sought.
It is ignored unless <structfield>bgw_main</structfield> is NULL. The named library will be dynamically loaded by the worker process and
But if <structfield>bgw_main</structfield> is NULL, then the named library <structfield>bgw_function_name</structfield> will be used to identify the
will be dynamically loaded by the worker process and function to be called. If loading a function from the core code,
<structfield>bgw_function_name</structfield> will be used to identify <structfield>bgw_main</> should be set instead.
the function to be called.
</para> </para>
<para> <para>
<structfield>bgw_function_name</structfield> is the name of a function in <structfield>bgw_function_name</structfield> is the name of a function in
a dynamically loaded library which should be used as the initial entry point a dynamically loaded library which should be used as the initial entry point
for a new background worker. It is ignored unless for a new background worker.
<structfield>bgw_main</structfield> is NULL. </para>
<para>
<structfield>bgw_main_arg</structfield> is the <type>Datum</> argument
to the background worker main function. Regardless of whether that
function is specified via <structfield>bgw_main</> or via the combination
of <function>bgw_library_name</> and <function>bgw_function_name</>,
this main function should take a single argument of type <type>Datum</>
and return <type>void</>. <structfield>bgw_main_arg</structfield> will be
passed as the argument. In addition, the global variable
<literal>MyBgworkerEntry</literal>
points to a copy of the <structname>BackgroundWorker</structname> structure
passed at registration time; the worker may find it helpful to examine
this structure.
</para>
<para>
On Windows (and anywhere else where <literal>EXEC_BACKEND</literal> is
defined) or in dynamic background workers it is not safe to pass a
<type>Datum</> by reference, only by value. If an argument is required, it
is safest to pass an int32 or other small value and use that as an index
into an array allocated in shared memory. If a value like a <type>cstring</>
or <type>text</type> is passed then the pointer won't be valid from the
new background worker process.
</para> </para>
<para> <para>