<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.197 2003/07/29 00:03:17 tgl Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.198 2003/07/31 18:36:17 tgl Exp $
-->
<Chapter Id="runtime">
<listitem>
<para>
This variable specifies one or more shared libraries that are
- to be preloaded at server start. An initialization function
- can also be optionally specified by adding a colon followed by
- the name of the initialization function after the library
- name. For example
- <literal>'$libdir/mylib:init_mylib'</literal> would cause
- <literal>mylib</> to be preloaded and <literal>init_mylib</>
- to be executed. If more than one library is to be loaded, they
- must be delimited with a comma.
+ 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 <literal>mylib</> is not found, the server will fail to
- start. However, if <literal>init_mylib</> is not found,
- <literal>mylib</> will still be preloaded without executing
- the initialization function.
+ If <literal>mylib</> or <literal>mylib_init</> are not found, the
+ server will fail to start.
+ </para>
+
+ <para>
+ PostgreSQL procedural language libraries may be preloaded in this way,
+ typically by using the syntax
+ <literal>'$libdir/plXXX:plXXX_init'</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
- server process may increase, even if that process never
- uses the library.
+ server process may increase, even if that process never
+ uses the library.
</para>
</listitem>
</varlistentry>
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.108 2003/07/28 00:09:16 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.109 2003/07/31 18:36:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
}
initfunc = (func_ptr) load_external_function(filename, funcname,
- false, NULL);
+ true, NULL);
if (initfunc)
(*initfunc)();
* ENHANCEMENTS, OR MODIFICATIONS.
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.37 2003/07/25 23:37:28 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.38 2003/07/31 18:36:28 tgl Exp $
*
**********************************************************************/
static void plperl_init_interp(void);
Datum plperl_call_handler(PG_FUNCTION_ARGS);
+void plperl_init(void);
static Datum plperl_func_handler(PG_FUNCTION_ARGS);
}
/**********************************************************************
- * plperl_init_all() - Initialize all
+ * plperl_init() - Initialize everything that can be
+ * safely initialized during postmaster
+ * startup.
+ *
+ * DO NOT make this static --- it has to be callable by preload
**********************************************************************/
-static void
-plperl_init_all(void)
+void
+plperl_init(void)
{
-
/************************************************************
* Do initialization only once
************************************************************/
plperl_firstcall = 0;
}
+/**********************************************************************
+ * plperl_init_all() - Initialize all
+ **********************************************************************/
+static void
+plperl_init_all(void)
+{
+
+ /************************************************************
+ * Execute postmaster-startup safe initialization
+ ************************************************************/
+ if (plperl_firstcall)
+ plperl_init();
+
+ /************************************************************
+ * Any other initialization that must be done each time a new
+ * backend starts -- currently none
+ ************************************************************/
+
+}
+
/**********************************************************************
* plperl_init_interp() - Create the Perl interpreter
Datum retval;
/************************************************************
- * Initialize interpreter on first call
+ * Initialize interpreter
************************************************************/
- if (plperl_firstcall)
- plperl_init_all();
+ plperl_init_all();
/************************************************************
* Connect to SPI manager
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.63 2003/07/27 21:49:54 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.64 2003/07/31 18:36:35 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
static void compute_function_hashkey(FmgrInfo *flinfo,
Form_pg_proc procStruct,
PLpgSQL_func_hashkey *hashkey);
-static void plpgsql_HashTableInit(void);
static PLpgSQL_function *plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key);
static void plpgsql_HashTableInsert(PLpgSQL_function *function,
PLpgSQL_func_hashkey *func_key);
}
}
-static void
+/* exported so we can call it from plpgsql_init() */
+void
plpgsql_HashTableInit(void)
{
HASHCTL ctl;
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.15 2003/07/27 17:10:07 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.16 2003/07/31 18:36:35 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
#include "utils/builtins.h"
#include "utils/syscache.h"
+static int plpgsql_firstcall = 1;
+
+void plpgsql_init(void);
+static void plpgsql_init_all(void);
+
+
+/*
+ * plpgsql_init() - postmaster-startup safe initialization
+ *
+ * DO NOT make this static --- it has to be callable by preload
+ */
+void
+plpgsql_init(void)
+{
+ /* Do initialization only once */
+ if (!plpgsql_firstcall)
+ return;
+
+ plpgsql_HashTableInit();
+
+ plpgsql_firstcall = 0;
+}
+
+/*
+ * plpgsql_init_all() - Initialize all
+ */
+static void
+plpgsql_init_all(void)
+{
+ /* Execute any postmaster-startup safe initialization */
+ if (plpgsql_firstcall)
+ plpgsql_init();
+
+ /*
+ * Any other initialization that must be done each time a new
+ * backend starts -- currently none
+ */
+
+}
/* ----------
* plpgsql_call_handler
PLpgSQL_function *func;
Datum retval;
+ /* perform initialization */
+ plpgsql_init_all();
+
/*
* Connect to SPI manager
*/
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.37 2003/07/01 21:47:09 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.38 2003/07/31 18:36:35 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
extern void plpgsql_adddatum(PLpgSQL_datum * new);
extern int plpgsql_add_initdatums(int **varnos);
extern void plpgsql_yyerror(const char *s);
+extern void plpgsql_HashTableInit(void);
/* ----------
* Functions in pl_handler.c
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpython/plpython.c,v 1.35 2003/07/25 23:37:30 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpython/plpython.c,v 1.36 2003/07/31 18:36:39 tgl Exp $
*
*********************************************************************
*/
/* function declarations
*/
-/* the only exported function, with the magic telling Postgresql
- * what function call interface it implements.
+/* Two exported functions: first is the magic telling Postgresql
+ * what function call interface it implements. Second allows
+ * preinitialization of the interpreter during postmaster startup.
*/
Datum plpython_call_handler(PG_FUNCTION_ARGS);
+void plpython_init(void);
PG_FUNCTION_INFO_V1(plpython_call_handler);
enter();
- if (PLy_first_call)
- PLy_init_all();
+ PLy_init_all();
if (SPI_connect() != SPI_OK_CONNECT)
elog(ERROR, "could not connect to SPI manager");
/* language handler and interpreter initialization
*/
+/*
+ * plpython_init() - Initialize everything that can be
+ * safely initialized during postmaster
+ * startup.
+ *
+ * DO NOT make this static --- it has to be callable by preload
+ */
void
-PLy_init_all(void)
+plpython_init(void)
{
static volatile int init_active = 0;
+ /* Do initialization only once */
+ if (!PLy_first_call)
+ return;
+
enter();
if (init_active)
leave();
}
+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
+ */
+
+}
+
void
PLy_init_interp(void)
{
* ENHANCEMENTS, OR MODIFICATIONS.
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.72 2003/07/25 23:37:31 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.73 2003/07/31 18:36:46 tgl Exp $
*
**********************************************************************/
/**********************************************************************
* Global data
**********************************************************************/
-static int pltcl_firstcall = 1;
+static bool pltcl_pm_init_done = false;
+static bool pltcl_be_init_done = false;
static int pltcl_call_level = 0;
static int pltcl_restart_in_progress = 0;
static Tcl_Interp *pltcl_hold_interp = NULL;
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);
fmgr_info_cxt(functionId, finfo, TopMemoryContext);
}
-
/**********************************************************************
- * pltcl_init_all() - Initialize all
+ * pltcl_init() - Initialize all that's safe to do in the postmaster
+ *
+ * DO NOT make this static --- it has to be callable by preload
**********************************************************************/
-static void
-pltcl_init_all(void)
+void
+pltcl_init(void)
{
/************************************************************
* Do initialization only once
************************************************************/
- if (!pltcl_firstcall)
+ if (pltcl_pm_init_done)
return;
/************************************************************
Tcl_InitHashTable(pltcl_norm_query_hash, TCL_STRING_KEYS);
Tcl_InitHashTable(pltcl_safe_query_hash, TCL_STRING_KEYS);
- pltcl_firstcall = 0;
- return;
+ pltcl_pm_init_done = true;
+}
+
+/**********************************************************************
+ * pltcl_init_all() - Initialize all
+ **********************************************************************/
+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
+ ************************************************************/
+ if (!pltcl_be_init_done)
+ {
+ if (SPI_connect() != SPI_OK_CONNECT)
+ elog(ERROR, "SPI_connect failed");
+ pltcl_init_load_unknown(pltcl_norm_interp);
+ pltcl_init_load_unknown(pltcl_safe_interp);
+ if (SPI_finish() != SPI_OK_FINISH)
+ elog(ERROR, "SPI_finish failed");
+ pltcl_be_init_done = true;
+ }
}
pltcl_SPI_execp, NULL, NULL);
Tcl_CreateCommand(interp, "spi_lastoid",
pltcl_SPI_lastoid, NULL, NULL);
-
- /************************************************************
- * Try to load the unknown procedure from pltcl_modules
- ************************************************************/
- if (SPI_connect() != SPI_OK_CONNECT)
- elog(ERROR, "SPI_connect failed");
- pltcl_init_load_unknown(interp);
- if (SPI_finish() != SPI_OK_FINISH)
- elog(ERROR, "SPI_finish failed");
}
FunctionCallInfo save_fcinfo;
/************************************************************
- * Initialize interpreters on first call
+ * Initialize interpreters
************************************************************/
- if (pltcl_firstcall)
- pltcl_init_all();
+ pltcl_init_all();
/************************************************************
* Connect to SPI manager