From b09bfcaa576c1a3e0c34a747a502bae909b984a8 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 8 Aug 2006 19:15:09 +0000 Subject: [PATCH] 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. --- doc/src/sgml/config.sgml | 33 +++++----- doc/src/sgml/xfunc.sgml | 99 +++++++++++++++++++---------- src/backend/postmaster/postmaster.c | 11 +--- src/backend/utils/fmgr/dfmgr.c | 27 +++++++- src/backend/utils/init/miscinit.c | 60 +++-------------- src/include/miscadmin.h | 6 +- src/include/postmaster/postmaster.h | 3 +- src/pl/plperl/plperl.c | 48 +++++--------- src/pl/plpgsql/src/pl_handler.c | 40 +++--------- src/pl/plpgsql/src/plpgsql.h | 4 +- src/pl/plpython/plpython.c | 47 ++++---------- src/pl/tcl/pltcl.c | 38 +++++------ 12 files changed, 178 insertions(+), 238 deletions(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index c1c42656ad..706ccba56c 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1,4 +1,4 @@ - + Server Configuration @@ -957,38 +957,35 @@ SET ENABLE_SEQSCAN TO OFF; 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 - '$libdir/mylib:mylib_init' would cause - mylib to be preloaded and mylib_init - to be executed. If more than one library is to be loaded, - separate their names with commas. - - - - 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, + '$libdir/mylib' would cause + mylib.so (or on some platforms, + mylib.sl) to be preloaded from the installation's + standard library directory. PostgreSQL procedural language libraries can be preloaded in this way, typically by using the - syntax '$libdir/plXXX:plXXX_init' where + syntax '$libdir/plXXX' where XXX is pgsql, perl, tcl, or python. - 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. + + If a specified library is not found, + the server will fail to start. + + Every PostgreSQL-supported library has a magic block that is checked to guarantee compatibility. diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml index 6321bf5b0a..ae6604f7a2 100644 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@ -1,4 +1,4 @@ - + User-Defined Functions @@ -1148,6 +1148,15 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision that fails as well, the load will fail. + + It is recommended to locate shared libraries either relative to + $libdir or through the dynamic library path. + This simplifies version upgrades if the new installation is at a + different location. The actual directory that + $libdir stands for can be found out with the + command pg_config --pkglibdir. + + The user ID the PostgreSQL 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 + + magic block + + + + To ensure that a dynamically loaded object file is not loaded into an + incompatible server, PostgreSQL checks that the + file contains a magic block with the appropriate contents. + This allows the server to detect obvious incompatibilities, such as code + compiled for a different major version of + PostgreSQL. A magic block is required as of + PostgreSQL 8.2. To include a magic block, + write this in one (and only one) of the module source files, after having + included the header fmgr.h: + + +#ifdef PG_MODULE_MAGIC +PG_MODULE_MAGIC; +#endif + + + The #ifdef test can be omitted if the code doesn't + need to compile against pre-8.2 PostgreSQL + releases. + + 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. + + _PG_init + + + _PG_fini + + + library initialization function + + + library finalization function + + - It is recommended to locate shared libraries either relative to - $libdir or through the dynamic library path. - This simplifies version upgrades if the new installation is at a - different location. The actual directory that - $libdir stands for can be found out with the - command pg_config --pkglibdir. + Optionally, a dynamically loaded file can contain initialization and + finalization functions. If the file includes a function named + _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 + _PG_fini, that function will be called immediately before + unloading the file. Likewise, the function receives no parameters and + should return void. Note that _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 LOAD command.) @@ -1910,31 +1963,6 @@ concat_text(PG_FUNCTION_ARGS) - - - To ensure your module is not loaded into an incompatible server, - it must include a magic block. This allows - the server to detect obvious incompatibilities, such as a module - compiled for a different major version of - PostgreSQL. A magic block is required - as of PostgreSQL 8.2. To include a magic - block, write this in one (and only one) of your module source files, - after having included the header fmgr.h: - - - -#ifdef PG_MODULE_MAGIC -PG_MODULE_MAGIC; -#endif - - - - The #ifdef test can be omitted if your code doesn't - need to compile against pre-8.2 PostgreSQL - releases. - - - Compiling and linking your code so that it can be dynamically @@ -1945,6 +1973,13 @@ PG_MODULE_MAGIC; + + + Remember to define a magic block for your shared library, + as described in . + + + When allocating memory, use the diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 13492bfec8..eefa974dee 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -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 diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c index 4c50e421e5..fd2c54c211 100644 --- a/src/backend/utils/fmgr/dfmgr.c +++ b/src/backend/utils/fmgr/dfmgr.c @@ -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 */ diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index 35d9da2a08..b238aaec5c 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -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); diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index 429b9929a5..07590c9294 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -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 */ diff --git a/src/include/postmaster/postmaster.h b/src/include/postmaster/postmaster.h index 8f0b21b3af..bf25b93d1a 100644 --- a/src/include/postmaster/postmaster.h +++ b/src/include/postmaster/postmaster.h @@ -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; diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 2ed16b12cb..8e0f309d05 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -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 */ diff --git a/src/pl/plpgsql/src/pl_handler.c b/src/pl/plpgsql/src/pl_handler.c index d8eb22f995..22264f5a28 100644 --- a/src/pl/plpgsql/src/pl_handler.c +++ b/src/pl/plpgsql/src/pl_handler.c @@ -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), diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h index 32d7fbaf69..268fc13821 100644 --- a/src/pl/plpgsql/src/plpgsql.h +++ b/src/pl/plpgsql/src/plpgsql.h @@ -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); diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c index 164df875a5..289ab2e7b7 100644 --- a/src/pl/plpython/plpython.c +++ b/src/pl/plpython/plpython.c @@ -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 diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c index 75964b2568..54abd09672 100644 --- a/src/pl/tcl/pltcl.c +++ b/src/pl/tcl/pltcl.c @@ -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,15 +120,14 @@ static pltcl_proc_desc *pltcl_current_prodesc = NULL; /********************************************************************** * 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); @@ -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) { -- 2.40.0