Patch to allow C extension modules to initialize/finish - Mailing list pgsql-hackers
| From | Ralf S. Engelschall |
|---|---|
| Subject | Patch to allow C extension modules to initialize/finish |
| Date | |
| Msg-id | 20060802190411.GA85749@engelschall.com Whole thread Raw |
| Responses |
Re: [BUGS] Patch to allow C extension modules to initialize/finish
Re: [BUGS] Patch to allow C extension modules to initialize/finish Re: [BUGS] Patch to allow C extension modules to initialize/finish |
| List | pgsql-hackers |
PostgreSQL provides a way to load C extension modules with its internal
FMGR. Unfortunately there is no portable way for an extension module to
initialize (directly after the pg_dlopen() of the DSO) and to finish
(directly before the pg_dlclose() of the DSO). This way it is mostly
impossible to write a more complex extension module in a portable way.
The only to me known workarounds are either to call an own
initialization function at the start of _EVERY_ exported function
manually (works, but is ugly and especially doesn't work for the
finishing function!) or to leverage some platform specific hacks like
the implicitly called _init and _fini functions (is what the ODBC
extension module currently does, but is horribly platform specific and
not portable).
Hence I propose the patch below (applies to PostgreSQL 8.1.4) which
mimics the dlopen(3) and dlclose(3) behaviour of some Unix platforms
and resolves and calls _PG_init and _PG_fini functions of an extension
module right after/before the pg_dlopen/pg_dlclose calls in the FMGR.
This is both a fully portable solution and fully backward compatible to
existing and forthcoming extension modules (except they really would
have _PG_init and _PG_fini functions already defined).
Ralf S. Engelschall rse@engelschall.com
www.engelschall.com
Index: src/backend/utils/fmgr/dfmgr.c
--- src/backend/utils/fmgr/dfmgr.c.orig 2005-10-15 04:49:32 +0200
+++ src/backend/utils/fmgr/dfmgr.c 2006-08-02 20:48:48 +0200
@@ -60,6 +60,10 @@static char *expand_dynamic_library_name(const char *name);static char
*substitute_libpath_macro(constchar *name);
+/* types for PostgreSQL-specific DSO init/fini functions */
+typedef void (*PG_init_t)(void);
+typedef void (*PG_fini_t)(void);
+/* * Load the specified dynamic-link library file, and look for a function * named funcname in it. (funcname can be
NULLto just load the file.)
@@ -82,6 +86,7 @@ char *load_error; struct stat stat_buf; char *fullname;
+ PG_init_t *PG_init;
fullname = expand_dynamic_library_name(filename); if (!fullname)
@@ -146,6 +151,13 @@ fullname, load_error))); }
+ /* optionally give the DSO a chance to initialize by calling a
+ PostgreSQL-specific (and this way portable) "_PG_init" function
+ similar to what dlopen(3) implicitly does with "_init" on some
+ Unix platforms. */
+ if ((PG_init = (PG_init_t *)pg_dlsym(file_scanner->handle, "_PG_init")) != NULL)
+ (*PG_init)();
+ /* OK to link it into list */ if (file_list == NULL) file_list = file_scanner;
@@ -192,6 +204,7 @@ *nxt; struct stat stat_buf; char *fullname;
+ PG_fini_t *PG_fini;
fullname = expand_dynamic_library_name(filename); if (!fullname)
@@ -224,6 +237,14 @@ else file_list = nxt;
clear_external_function_hash(file_scanner->handle);
+
+ /* optionally give the DSO a chance to finish by calling
+ a PostgreSQL-specific (and this way portable) "_PG_fini"
+ function similar to what dlopen(3) implicitly does with
+ "_fini" on some Unix platforms. */
+ if ((PG_fini = (PG_init_t *)pg_dlsym(file_scanner->handle, "_PG_fini")) != NULL)
+ (*PG_fini)();
+ pg_dlclose(file_scanner->handle); free((char *) file_scanner); /* prv does not
change*/
pgsql-hackers by date: