Add a feature for automatic initialization and finalization of dynamically

loaded libraries: call functions _PG_init() and _PG_fini() if the library
defines such symbols.  Hence we no longer need to specify an initialization
function in preload_libraries: we can assume that the library used the
_PG_init() convention, instead.  This removes one source of pilot error
in use of preloaded libraries.  Original patch by Ralf Engelschall,
preload_libraries changes by me.
This commit is contained in:
Tom Lane 2006-08-08 19:15:09 +00:00
parent e00664da48
commit b09bfcaa57
12 changed files with 179 additions and 239 deletions

View File

@ -1,4 +1,4 @@
<!-- $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>
@ -957,38 +957,35 @@ SET ENABLE_SEQSCAN TO OFF;
<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.

View File

@ -1,4 +1,4 @@
<!-- $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>
@ -1148,6 +1148,15 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision
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
@ -1173,6 +1182,32 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision
</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
@ -1183,13 +1218,31 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision
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>
@ -1910,31 +1963,6 @@ concat_text(PG_FUNCTION_ARGS)
</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
@ -1945,6 +1973,13 @@ PG_MODULE_MAGIC;
</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

View File

@ -37,7 +37,7 @@
*
*
* 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
*
@ -197,9 +197,6 @@ bool Db_user_namespace = false;
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,
@ -710,11 +707,9 @@ PostmasterMain(int argc, char *argv[])
#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

View File

@ -8,7 +8,7 @@
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
@ -25,6 +25,10 @@
#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).
*/
@ -79,7 +83,7 @@ static const Pg_magic_struct magic_data = PG_MODULE_MAGIC_DATA;
* 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)
@ -90,6 +94,7 @@ load_external_function(char *filename, char *funcname,
char *load_error;
struct stat stat_buf;
char *fullname;
PG_init_t PG_init;
fullname = expand_dynamic_library_name(filename);
if (!fullname)
@ -201,7 +206,14 @@ load_external_function(char *filename, char *funcname,
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;
@ -248,6 +260,7 @@ load_file(char *filename)
*nxt;
struct stat stat_buf;
char *fullname;
PG_fini_t PG_fini;
fullname = expand_dynamic_library_name(filename);
if (!fullname)
@ -280,6 +293,14 @@ load_file(char *filename)
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 */

View File

@ -8,7 +8,7 @@
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
@ -1097,14 +1097,14 @@ ValidatePgVersion(const char *path)
*-------------------------------------------------------------------------
*/
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;
@ -1131,54 +1131,14 @@ process_preload_libraries(char *preload_libraries_string)
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);

View File

@ -13,7 +13,7 @@
* 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.
@ -307,6 +307,8 @@ extern void BaseInit(void);
/* 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);
@ -317,6 +319,6 @@ extern void TouchSocketLockFile(void);
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 */

View File

@ -6,7 +6,7 @@
* 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 $
*
*-------------------------------------------------------------------------
*/
@ -25,7 +25,6 @@ extern char *ListenAddresses;
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;

View File

@ -1,7 +1,7 @@
/**********************************************************************
* 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 $
*
**********************************************************************/
@ -87,7 +87,6 @@ typedef struct plperl_query_desc
/**********************************************************************
* 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;
@ -101,12 +100,11 @@ static plperl_call_data *current_call_data = 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);
@ -135,16 +133,21 @@ perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
}
/* 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,
@ -154,19 +157,8 @@ plperl_init(void)
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 */
@ -657,8 +649,6 @@ plperl_call_handler(PG_FUNCTION_ARGS)
Datum retval;
plperl_call_data *save_call_data;
plperl_init_all();
save_call_data = current_call_data;
PG_TRY();
{
@ -741,11 +731,7 @@ plperl_validator(PG_FUNCTION_ARGS)
/* 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 */

View File

@ -8,7 +8,7 @@
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
@ -28,41 +28,25 @@ extern DLLIMPORT bool check_function_bodies;
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;
}
/* ----------
@ -81,9 +65,6 @@ plpgsql_call_handler(PG_FUNCTION_ARGS)
Datum retval;
int rc;
/* perform initialization */
plpgsql_init_all();
/*
* Connect to SPI manager
*/
@ -135,9 +116,6 @@ plpgsql_validator(PG_FUNCTION_ARGS)
bool istrigger = false;
int i;
/* perform initialization */
plpgsql_init_all();
/* Get the new function's pg_proc entry */
tuple = SearchSysCache(PROCOID,
ObjectIdGetDatum(funcoid),

View File

@ -8,7 +8,7 @@
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
@ -678,7 +678,7 @@ extern void plpgsql_compile_error_callback(void *arg);
* 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);

View File

@ -1,7 +1,7 @@
/**********************************************************************
* 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 $
*
*********************************************************************
*/
@ -155,11 +155,11 @@ typedef struct PLyResultObject
/* 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);
@ -169,7 +169,6 @@ 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);
@ -233,9 +232,6 @@ static PyObject *PLyLong_FromString(const char *);
static PyObject *PLyString_FromString(const char *);
/* global data */
static bool PLy_first_call = true;
/*
* Currently active plpython function
*/
@ -301,8 +297,6 @@ plpython_call_handler(PG_FUNCTION_ARGS)
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");
@ -2263,25 +2257,19 @@ PLy_spi_execute_fetch_result(SPITupleTable *tuptable, int rows, int status)
*/
/*
* 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();
@ -2291,20 +2279,7 @@ plpython_init(void)
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

View File

@ -2,7 +2,7 @@
* 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 $
*
**********************************************************************/
@ -120,14 +120,13 @@ static pltcl_proc_desc *pltcl_current_prodesc = NULL;
/**********************************************************************
* Forward declarations
**********************************************************************/
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);
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);
static Datum pltcl_func_handler(PG_FUNCTION_ARGS);
@ -182,17 +181,15 @@ perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
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;
@ -236,20 +233,15 @@ pltcl_init(void)
/**********************************************************************
* 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)
{