-<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.72 2006/08/08 01:23:15 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.73 2006/08/08 19:15:07 tgl Exp $ -->
<chapter Id="runtime-config">
<title>Server Configuration</title>
<listitem>
<para>
This variable specifies one or more shared libraries that are
- to be preloaded at server start. A parameterless
- initialization function can optionally be called for each
- library. To specify that, add a colon and the name of the
- initialization function after the library name. For example
- <literal>'$libdir/mylib:mylib_init'</literal> would cause
- <literal>mylib</> to be preloaded and <literal>mylib_init</>
- to be executed. If more than one library is to be loaded,
- separate their names with commas.
- </para>
-
- <para>
- If a specified library or initialization function is not found,
- the server will fail to start.
+ to be preloaded at server start. If more than one library is to be
+ loaded, separate their names with commas. For example,
+ <literal>'$libdir/mylib'</literal> would cause
+ <literal>mylib.so</> (or on some platforms,
+ <literal>mylib.sl</>) to be preloaded from the installation's
+ standard library directory.
</para>
<para>
<productname>PostgreSQL</productname> procedural language
libraries can be preloaded in this way, typically by using the
- syntax <literal>'$libdir/plXXX:plXXX_init'</literal> where
+ syntax <literal>'$libdir/plXXX'</literal> where
<literal>XXX</literal> is <literal>pgsql</>, <literal>perl</>,
<literal>tcl</>, or <literal>python</>.
</para>
<para>
- By preloading a shared library (and initializing it if
- applicable), the library startup time is avoided when the
- library is first used. However, the time to start each new
+ By preloading a shared library, the library startup time is avoided
+ when the library is first used. However, the time to start each new
server process may increase slightly, even if that process never
uses the library. So this parameter is recommended only for
libraries that will be used in most sessions.
</para>
+ <para>
+ If a specified library is not found,
+ the server will fail to start.
+ </para>
+
<para>
Every PostgreSQL-supported library has a <quote>magic
block</> that is checked to guarantee compatibility.
-<!-- $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.115 2006/05/31 20:58:09 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.116 2006/08/08 19:15:07 tgl Exp $ -->
<sect1 id="xfunc">
<title>User-Defined Functions</title>
that fails as well, the load will fail.
</para>
+ <para>
+ It is recommended to locate shared libraries either relative to
+ <literal>$libdir</literal> or through the dynamic library path.
+ This simplifies version upgrades if the new installation is at a
+ different location. The actual directory that
+ <literal>$libdir</literal> stands for can be found out with the
+ command <literal>pg_config --pkglibdir</literal>.
+ </para>
+
<para>
The user ID the <productname>PostgreSQL</productname> server runs
as must be able to traverse the path to the file you intend to
</para>
</note>
+ <indexterm zone="xfunc-c-dynload">
+ <primary>magic block</primary>
+ </indexterm>
+
+ <para>
+ To ensure that a dynamically loaded object file is not loaded into an
+ incompatible server, <productname>PostgreSQL</productname> checks that the
+ file contains a <quote>magic block</> with the appropriate contents.
+ This allows the server to detect obvious incompatibilities, such as code
+ compiled for a different major version of
+ <productname>PostgreSQL</productname>. A magic block is required as of
+ <productname>PostgreSQL</productname> 8.2. To include a magic block,
+ write this in one (and only one) of the module source files, after having
+ included the header <filename>fmgr.h</>:
+
+<programlisting>
+#ifdef PG_MODULE_MAGIC
+PG_MODULE_MAGIC;
+#endif
+</programlisting>
+
+ The <literal>#ifdef</> test can be omitted if the code doesn't
+ need to compile against pre-8.2 <productname>PostgreSQL</productname>
+ releases.
+ </para>
+
<para>
After it is used for the first time, a dynamically loaded object
file is retained in memory. Future calls in the same session to
fresh session.
</para>
+ <indexterm zone="xfunc-c-dynload">
+ <primary>_PG_init</primary>
+ </indexterm>
+ <indexterm zone="xfunc-c-dynload">
+ <primary>_PG_fini</primary>
+ </indexterm>
+ <indexterm zone="xfunc-c-dynload">
+ <primary>library initialization function</primary>
+ </indexterm>
+ <indexterm zone="xfunc-c-dynload">
+ <primary>library finalization function</primary>
+ </indexterm>
+
<para>
- It is recommended to locate shared libraries either relative to
- <literal>$libdir</literal> or through the dynamic library path.
- This simplifies version upgrades if the new installation is at a
- different location. The actual directory that
- <literal>$libdir</literal> stands for can be found out with the
- command <literal>pg_config --pkglibdir</literal>.
+ Optionally, a dynamically loaded file can contain initialization and
+ finalization functions. If the file includes a function named
+ <literal>_PG_init</>, that function will be called immediately after
+ loading the file. The function receives no parameters and should
+ return void. If the file includes a function named
+ <literal>_PG_fini</>, that function will be called immediately before
+ unloading the file. Likewise, the function receives no parameters and
+ should return void. Note that <literal>_PG_fini</> will only be called
+ during an unload of the file, not during process termination.
+ (Presently, an unload only happens in the context of re-loading
+ the file due to an explicit <command>LOAD</> command.)
</para>
</sect2>
</para>
</listitem>
- <listitem>
- <para>
- To ensure your module is not loaded into an incompatible server,
- it must include a <quote>magic block</>. This allows
- the server to detect obvious incompatibilities, such as a module
- compiled for a different major version of
- <productname>PostgreSQL</productname>. A magic block is required
- as of <productname>PostgreSQL</productname> 8.2. To include a magic
- block, write this in one (and only one) of your module source files,
- after having included the header <filename>fmgr.h</>:
- </para>
-
-<programlisting>
-#ifdef PG_MODULE_MAGIC
-PG_MODULE_MAGIC;
-#endif
-</programlisting>
-
- <para>
- The <literal>#ifdef</> test can be omitted if your code doesn't
- need to compile against pre-8.2 <productname>PostgreSQL</productname>
- releases.
- </para>
- </listitem>
-
<listitem>
<para>
Compiling and linking your code so that it can be dynamically
</para>
</listitem>
+ <listitem>
+ <para>
+ Remember to define a <quote>magic block</> for your shared library,
+ as described in <xref linkend="xfunc-c-dynload">.
+ </para>
+ </listitem>
+
<listitem>
<para>
When allocating memory, use the
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.497 2006/07/29 03:02:55 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.498 2006/08/08 19:15:07 tgl Exp $
*
* NOTES
*
char *bonjour_name;
-/* list of library:init-function to be preloaded */
-char *preload_libraries_string = NULL;
-
/* PIDs of special child processes; 0 when not running */
static pid_t StartupPID = 0,
BgWriterPID = 0,
#endif
/*
- * process any libraries that should be preloaded and optionally
- * pre-initialized
+ * process any libraries that should be preloaded at postmaster start
*/
- if (preload_libraries_string)
- process_preload_libraries(preload_libraries_string);
+ process_preload_libraries();
/*
* Remove old temporary files. At this point there can be no other
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.86 2006/06/07 22:24:44 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.87 2006/08/08 19:15:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "utils/dynamic_loader.h"
+/* signatures for PostgreSQL-specific library init/fini functions */
+typedef void (*PG_init_t)(void);
+typedef void (*PG_fini_t)(void);
+
/*
* List of dynamically loaded files (kept in malloc'd memory).
*/
* identifying the library file. The filehandle can be used with
* lookup_external_function to lookup additional functions in the same file
* at less cost than repeating load_external_function.
- */
+ */
PGFunction
load_external_function(char *filename, char *funcname,
bool signalNotFound, void **filehandle)
char *load_error;
struct stat stat_buf;
char *fullname;
+ PG_init_t PG_init;
fullname = expand_dynamic_library_name(filename);
if (!fullname)
fullname),
errhint("Extension libraries are now required to use the PG_MODULE_MAGIC macro.")));
}
-
+
+ /*
+ * If the library has a _PG_init() function, call it.
+ */
+ PG_init = (PG_init_t) pg_dlsym(file_scanner->handle, "_PG_init");
+ if (PG_init)
+ (*PG_init)();
+
/* OK to link it into list */
if (file_list == NULL)
file_list = file_scanner;
*nxt;
struct stat stat_buf;
char *fullname;
+ PG_fini_t PG_fini;
fullname = expand_dynamic_library_name(filename);
if (!fullname)
else
file_list = nxt;
clear_external_function_hash(file_scanner->handle);
+
+ /*
+ * If the library has a _PG_fini() function, call it.
+ */
+ PG_fini = (PG_fini_t) pg_dlsym(file_scanner->handle, "_PG_fini");
+ if (PG_fini)
+ (*PG_fini)();
+
pg_dlclose(file_scanner->handle);
free((char *) file_scanner);
/* prv does not change */
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.155 2006/07/14 14:52:25 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.156 2006/08/08 19:15:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
*-------------------------------------------------------------------------
*/
-typedef void (*func_ptr) ();
+/* GUC variable: list of library names to be preloaded */
+char *preload_libraries_string = NULL;
/*
- * process any libraries that should be preloaded and
- * optionally pre-initialized
+ * process any libraries that should be preloaded at postmaster start
*/
void
-process_preload_libraries(char *preload_libraries_string)
+process_preload_libraries(void)
{
char *rawstring;
List *elemlist;
foreach(l, elemlist)
{
char *tok = (char *) lfirst(l);
- char *sep = strstr(tok, ":");
- char *filename = NULL;
- char *funcname = NULL;
- func_ptr initfunc;
-
- if (sep)
- {
- /*
- * a colon separator implies there is an initialization function
- * that we need to run in addition to loading the library
- */
- size_t filename_len = sep - tok;
- size_t funcname_len = strlen(tok) - filename_len - 1;
-
- filename = (char *) palloc(filename_len + 1);
- memcpy(filename, tok, filename_len);
- filename[filename_len] = '\0';
-
- funcname = (char *) palloc(funcname_len + 1);
- strcpy(funcname, sep + 1);
- }
- else
- {
- /*
- * no separator -- just load the library
- */
- filename = pstrdup(tok);
- funcname = NULL;
- }
+ char *filename;
+ filename = pstrdup(tok);
canonicalize_path(filename);
- initfunc = (func_ptr) load_external_function(filename, funcname,
- true, NULL);
- if (initfunc)
- (*initfunc) ();
-
- if (funcname)
- ereport(LOG,
- (errmsg("preloaded library \"%s\" with initialization function \"%s\"",
- filename, funcname)));
- else
- ereport(LOG,
- (errmsg("preloaded library \"%s\"",
- filename)));
-
+ (void) load_external_function(filename, NULL, true, NULL);
+ ereport(LOG,
+ (errmsg("preloaded library \"%s\"", filename)));
pfree(filename);
- if (funcname)
- pfree(funcname);
}
pfree(rawstring);
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.186 2006/03/05 15:58:53 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.187 2006/08/08 19:15:08 tgl Exp $
*
* NOTES
* some of the information in this file should be moved to other files.
/* in utils/init/miscinit.c */
extern bool IgnoreSystemIndexes;
+extern char *preload_libraries_string;
+
extern void SetReindexProcessing(Oid heapOid, Oid indexOid);
extern void ResetReindexProcessing(void);
extern bool ReindexIsProcessingHeap(Oid heapOid);
extern void RecordSharedMemoryInLockFile(unsigned long id1,
unsigned long id2);
extern void ValidatePgVersion(const char *path);
-extern void process_preload_libraries(char *preload_libraries_string);
+extern void process_preload_libraries(void);
#endif /* MISCADMIN_H */
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/postmaster/postmaster.h,v 1.13 2006/03/05 15:58:58 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/postmaster/postmaster.h,v 1.14 2006/08/08 19:15:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern bool ClientAuthInProgress;
extern int PreAuthDelay;
extern int AuthenticationTimeout;
-extern char *preload_libraries_string;
extern bool Log_connections;
extern bool log_hostname;
extern char *bonjour_name;
/**********************************************************************
* plperl.c - perl as a procedural language for PostgreSQL
*
- * $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.112 2006/06/16 18:42:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.113 2006/08/08 19:15:09 tgl Exp $
*
**********************************************************************/
/**********************************************************************
* Global data
**********************************************************************/
-static bool plperl_firstcall = true;
static bool plperl_safe_init_done = false;
static PerlInterpreter *plperl_interp = NULL;
static HV *plperl_proc_hash = NULL;
/**********************************************************************
* Forward declarations
**********************************************************************/
-static void plperl_init_all(void);
-static void plperl_init_interp(void);
-
Datum plperl_call_handler(PG_FUNCTION_ARGS);
Datum plperl_validator(PG_FUNCTION_ARGS);
-void plperl_init(void);
+void _PG_init(void);
+
+static void plperl_init_interp(void);
static Datum plperl_func_handler(PG_FUNCTION_ARGS);
}
-/* Perform initialization during postmaster startup. */
-
+/*
+ * _PG_init() - library load-time initialization
+ *
+ * DO NOT make this static nor change its name!
+ */
void
-plperl_init(void)
+_PG_init(void)
{
- if (!plperl_firstcall)
+ /* Be sure we do initialization only once (should be redundant now) */
+ static bool inited = false;
+
+ if (inited)
return;
- DefineCustomBoolVariable(
- "plperl.use_strict",
+ DefineCustomBoolVariable("plperl.use_strict",
"If true, will compile trusted and untrusted perl code in strict mode",
NULL,
&plperl_use_strict,
EmitWarningsOnPlaceholders("plperl");
plperl_init_interp();
- plperl_firstcall = false;
-}
-
-
-/* Perform initialization during backend startup. */
-static void
-plperl_init_all(void)
-{
- if (plperl_firstcall)
- plperl_init();
-
- /* We don't need to do anything yet when a new backend starts. */
+ inited = true;
}
/* Each of these macros must represent a single string literal */
Datum retval;
plperl_call_data *save_call_data;
- plperl_init_all();
-
save_call_data = current_call_data;
PG_TRY();
{
/* Postpone body checks if !check_function_bodies */
if (check_function_bodies)
{
- plperl_proc_desc *prodesc;
-
- plperl_init_all();
-
- prodesc = compile_plperl_function(funcoid, istrigger);
+ (void) compile_plperl_function(funcoid, istrigger);
}
/* the result of a validator is ignored */
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.29 2006/05/30 22:12:16 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.30 2006/08/08 19:15:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
PG_MODULE_MAGIC;
-static bool plpgsql_firstcall = true;
-
-static void plpgsql_init_all(void);
-
/*
- * plpgsql_init() - postmaster-startup safe initialization
+ * _PG_init() - library load-time initialization
*
- * DO NOT make this static --- it has to be callable by preload
+ * DO NOT make this static nor change its name!
*/
void
-plpgsql_init(void)
+_PG_init(void)
{
- /* Do initialization only once */
- if (!plpgsql_firstcall)
+ /* Be sure we do initialization only once (should be redundant now) */
+ static bool inited = false;
+
+ if (inited)
return;
plpgsql_HashTableInit();
RegisterXactCallback(plpgsql_xact_cb, NULL);
- plpgsql_firstcall = false;
-}
-
-/*
- * plpgsql_init_all() - Initialize all
- */
-static void
-plpgsql_init_all(void)
-{
- /* Execute any postmaster-startup safe initialization */
- plpgsql_init();
- /*
- * Any other initialization that must be done each time a new backend
- * starts -- currently none
- */
+ inited = true;
}
/* ----------
Datum retval;
int rc;
- /* perform initialization */
- plpgsql_init_all();
-
/*
* Connect to SPI manager
*/
bool istrigger = false;
int i;
- /* perform initialization */
- plpgsql_init_all();
-
/* Get the new function's pg_proc entry */
tuple = SearchSysCache(PROCOID,
ObjectIdGetDatum(funcoid),
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.77 2006/07/11 17:26:59 momjian Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.78 2006/08/08 19:15:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* Functions in pl_handler.c
* ----------
*/
-extern void plpgsql_init(void);
+extern void _PG_init(void);
extern Datum plpgsql_call_handler(PG_FUNCTION_ARGS);
extern Datum plpgsql_validator(PG_FUNCTION_ARGS);
/**********************************************************************
* plpython.c - python as a procedural language for PostgreSQL
*
- * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.84 2006/07/06 01:55:51 momjian Exp $
+ * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.85 2006/08/08 19:15:09 tgl Exp $
*
*********************************************************************
*/
/* function declarations */
/* Two exported functions: first is the magic telling Postgresql
- * what function call interface it implements. Second allows
- * preinitialization of the interpreter during postmaster startup.
+ * what function call interface it implements. Second is for
+ * initialization of the interpreter during library load.
*/
Datum plpython_call_handler(PG_FUNCTION_ARGS);
-void plpython_init(void);
+void _PG_init(void);
PG_FUNCTION_INFO_V1(plpython_call_handler);
* of plpython_call_handler. initialize the python interpreter
* and global data.
*/
-static void PLy_init_all(void);
static void PLy_init_interp(void);
static void PLy_init_plpy(void);
static PyObject *PLyString_FromString(const char *);
-/* global data */
-static bool PLy_first_call = true;
-
/*
* Currently active plpython function
*/
PLyProcedure *save_curr_proc;
PLyProcedure *volatile proc = NULL;
- PLy_init_all();
-
if (SPI_connect() != SPI_OK_CONNECT)
elog(ERROR, "could not connect to SPI manager");
*/
/*
- * plpython_init() - Initialize everything that can be
- * safely initialized during postmaster
- * startup.
+ * _PG_init() - library load-time initialization
*
- * DO NOT make this static --- it has to be callable by preload
+ * DO NOT make this static nor change its name!
*/
void
-plpython_init(void)
+_PG_init(void)
{
- static volatile bool init_active = false;
+ /* Be sure we do initialization only once (should be redundant now) */
+ static bool inited = false;
- /* Do initialization only once */
- if (!PLy_first_call)
+ if (inited)
return;
- if (init_active)
- elog(FATAL, "initialization of language module failed");
- init_active = true;
-
Py_Initialize();
PLy_init_interp();
PLy_init_plpy();
if (PLy_procedure_cache == NULL)
PLy_elog(ERROR, "could not create procedure cache");
- PLy_first_call = false;
-}
-
-static void
-PLy_init_all(void)
-{
- /* Execute postmaster-startup safe initialization */
- if (PLy_first_call)
- plpython_init();
-
- /*
- * Any other initialization that must be done each time a new backend
- * starts -- currently none
- */
+ inited = true;
}
static void
* pltcl.c - PostgreSQL support for Tcl as
* procedural language (PL)
*
- * $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.105 2006/06/16 18:42:24 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.106 2006/08/08 19:15:09 tgl Exp $
*
**********************************************************************/
/**********************************************************************
* Forward declarations
**********************************************************************/
+Datum pltcl_call_handler(PG_FUNCTION_ARGS);
+Datum pltclu_call_handler(PG_FUNCTION_ARGS);
+void _PG_init(void);
+
static void pltcl_init_all(void);
static void pltcl_init_interp(Tcl_Interp *interp);
-
static void pltcl_init_load_unknown(Tcl_Interp *interp);
-Datum pltcl_call_handler(PG_FUNCTION_ARGS);
-Datum pltclu_call_handler(PG_FUNCTION_ARGS);
-void pltcl_init(void);
-
static Datum pltcl_func_handler(PG_FUNCTION_ARGS);
static HeapTuple pltcl_trigger_handler(PG_FUNCTION_ARGS);
fmgr_info_cxt(functionId, finfo, TopMemoryContext);
}
-/**********************************************************************
- * pltcl_init() - Initialize all that's safe to do in the postmaster
+/*
+ * _PG_init() - library load-time initialization
*
- * DO NOT make this static --- it has to be callable by preload
- **********************************************************************/
+ * DO NOT make this static nor change its name!
+ */
void
-pltcl_init(void)
+_PG_init(void)
{
- /************************************************************
- * Do initialization only once
- ************************************************************/
+ /* Be sure we do initialization only once (should be redundant now) */
if (pltcl_pm_init_done)
return;
/**********************************************************************
* pltcl_init_all() - Initialize all
+ *
+ * This does initialization that can't be done in the postmaster, and
+ * hence is not safe to do at library load time.
**********************************************************************/
static void
pltcl_init_all(void)
{
/************************************************************
- * Execute postmaster-startup safe initialization
- ************************************************************/
- if (!pltcl_pm_init_done)
- pltcl_init();
-
- /************************************************************
- * Any other initialization that must be done each time a new
- * backend starts:
- * - Try to load the unknown procedure from pltcl_modules
+ * Try to load the unknown procedure from pltcl_modules
************************************************************/
if (!pltcl_be_init_done)
{