summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/postmaster/postmaster.c11
-rw-r--r--src/backend/utils/fmgr/dfmgr.c27
-rw-r--r--src/backend/utils/init/miscinit.c60
-rw-r--r--src/include/miscadmin.h6
-rw-r--r--src/include/postmaster/postmaster.h3
-rw-r--r--src/pl/plperl/plperl.c48
-rw-r--r--src/pl/plpgsql/src/pl_handler.c40
-rw-r--r--src/pl/plpgsql/src/plpgsql.h4
-rw-r--r--src/pl/plpython/plpython.c47
-rw-r--r--src/pl/tcl/pltcl.c38
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)
{