diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/backend/postmaster/postmaster.c | 11 | ||||
| -rw-r--r-- | src/backend/utils/fmgr/dfmgr.c | 27 | ||||
| -rw-r--r-- | src/backend/utils/init/miscinit.c | 60 | ||||
| -rw-r--r-- | src/include/miscadmin.h | 6 | ||||
| -rw-r--r-- | src/include/postmaster/postmaster.h | 3 | ||||
| -rw-r--r-- | src/pl/plperl/plperl.c | 48 | ||||
| -rw-r--r-- | src/pl/plpgsql/src/pl_handler.c | 40 | ||||
| -rw-r--r-- | src/pl/plpgsql/src/plpgsql.h | 4 | ||||
| -rw-r--r-- | src/pl/plpython/plpython.c | 47 | ||||
| -rw-r--r-- | src/pl/tcl/pltcl.c | 38 |
10 files changed, 96 insertions, 188 deletions
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 13492bfec8b..eefa974dee9 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 4c50e421e57..fd2c54c2118 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 35d9da2a08a..b238aaec5ce 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 429b9929a59..07590c92942 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 8f0b21b3af3..bf25b93d1a1 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 2ed16b12cbe..8e0f309d056 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 d8eb22f995e..22264f5a283 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 32d7fbaf696..268fc13821e 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 164df875a5a..289ab2e7b73 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 75964b25684..54abd096722 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) { |
