Add a feature for automatic initialization and finalization of dynamically
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 8 Aug 2006 19:15:09 +0000 (19:15 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 8 Aug 2006 19:15:09 +0000 (19:15 +0000)
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.

12 files changed:
doc/src/sgml/config.sgml
doc/src/sgml/xfunc.sgml
src/backend/postmaster/postmaster.c
src/backend/utils/fmgr/dfmgr.c
src/backend/utils/init/miscinit.c
src/include/miscadmin.h
src/include/postmaster/postmaster.h
src/pl/plperl/plperl.c
src/pl/plpgsql/src/pl_handler.c
src/pl/plpgsql/src/plpgsql.h
src/pl/plpython/plpython.c
src/pl/tcl/pltcl.c

index c1c42656ad74aee600b495a31695d33afbb71aa5..706ccba56c871217ec9160e877d949e3dfcfb3c7 100644 (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.  
index 6321bf5b0a71b63835224ff4ef3e692f0b6e3d5e..ae6604f7a27d189307461ab4144d852017679b9c 100644 (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
index 13492bfec8b8f89eb2f4a35e22a624e785862c92..eefa974dee9f38a5d959e8ed40c6a8d2b9acb692 100644 (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
index 4c50e421e571cde658d250532e18206858a86879..fd2c54c2118ae1a33519f6d49b38d0f4df54fa34 100644 (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 $
  *
  *-------------------------------------------------------------------------
  */
 #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 */
index 35d9da2a08a5398c086468c748fa29d5cc783a16..b238aaec5ce7ad90295e5e128abc4f11d8b923b4 100644 (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);
index 429b9929a5977ceb631ea4a2f1749a38e8e04ad2..07590c92942327858045e83ff73cfc252367a76f 100644 (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 */
index 8f0b21b3af39838215ade6d8f29505818c3accdb..bf25b93d1a16e1f1cdc8b57d237c1dbf579ca592 100644 (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;
index 2ed16b12cbeb1f7b7522d3f2a15351536046a911..8e0f309d056cc21bd2ef59f2401a8e1c394cb1b5 100644 (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 */
index d8eb22f995e84f1ec5a348592e88f8d614a73757..22264f5a2837aadc1accf8a09510bc12fdb82e3e 100644 (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),
index 32d7fbaf69610078254e24dc2a1f4cca0e4886c4..268fc13821eb3b77ca52ee0a4949cbecd640d753 100644 (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);
 
index 164df875a5ae78109149b1231bfc9849dafd6731..289ab2e7b738cca3aa3ac9e8888e967c33e1cfea 100644 (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
index 75964b2568424ce8e46c0e7a574f4626fd98e4e8..54abd0967229aca033052891b1c7937a1dd114c5 100644 (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,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)
    {