aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/init/miscinit.c
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2003-03-20 04:51:44 +0000
committerBruce Momjian <bruce@momjian.us>2003-03-20 04:51:44 +0000
commit15ce2d2e4a3e9ae70801a5caa07579200a66b510 (patch)
tree6adec7f9487d6af68091139a0f93c260cd54c869 /src/backend/utils/init/miscinit.c
parente733510d5d67a0b4fb1a9228df598034e487f194 (diff)
downloadpostgresql-15ce2d2e4a3e9ae70801a5caa07579200a66b510.tar.gz
postgresql-15ce2d2e4a3e9ae70801a5caa07579200a66b510.zip
> I can see a couple possible downsides: (a) the library might have some
> weird behavior across fork boundaries; (b) the additional memory space > that has to be duplicated into child processes will cost something per > child launch, even if the child never uses it. But these are only > arguments that it might not *always* be a prudent thing to do, not that > we shouldn't give the DBA the tool to do it if he wants. So fire away. Here is a patch for the above, including a documentation update. It creates a new GUC variable "preload_libraries", that accepts a list in the form: preload_libraries = '$libdir/mylib1:initfunc,$libdir/mylib2' If ":initfunc" is omitted or not found, no initialization function is executed, but the library is still preloaded. If "$libdir/mylib" isn't found, the postmaster refuses to start. In my testing with PL/R, it reduces the first call to a PL/R function (after connecting) from almost 2 seconds, down to about 8 ms. Joe Conway
Diffstat (limited to 'src/backend/utils/init/miscinit.c')
-rw-r--r--src/backend/utils/init/miscinit.c91
1 files changed, 90 insertions, 1 deletions
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 12154396193..8b49ca2e584 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.100 2003/01/27 00:51:06 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.101 2003/03/20 04:51:44 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1044,3 +1044,92 @@ ValidatePgVersion(const char *path)
"which is not compatible with this version %s.",
file_major, file_minor, version_string);
}
+
+/*-------------------------------------------------------------------------
+ * Library preload support
+ *-------------------------------------------------------------------------
+ */
+
+#if defined(__mc68000__) && defined(__ELF__)
+typedef int32 ((*func_ptr) ());
+#else
+typedef char *((*func_ptr) ());
+#endif
+
+/*
+ * process any libraries that should be preloaded and
+ * optionally pre-initialized
+ */
+void
+process_preload_libraries(char *preload_libraries_string)
+{
+ char *rawstring;
+ List *elemlist;
+ List *l;
+
+ if (preload_libraries_string == NULL)
+ return;
+
+ /* Need a modifiable copy of string */
+ rawstring = pstrdup(preload_libraries_string);
+
+ /* Parse string into list of identifiers */
+ if (!SplitIdentifierString(rawstring, ',', &elemlist))
+ {
+ /* syntax error in list */
+ pfree(rawstring);
+ freeList(elemlist);
+ elog(LOG, "invalid list syntax for preload_libraries configuration option");
+ }
+
+ 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);
+ memset(filename, '\0', filename_len + 1);
+ snprintf(filename, filename_len + 1, "%s", tok);
+
+ funcname = (char *) palloc(funcname_len + 1);
+ memset(funcname, '\0', funcname_len + 1);
+ snprintf(funcname, funcname_len + 1, "%s", sep + 1);
+ }
+ else
+ {
+ /*
+ * no separator -- just load the library
+ */
+ filename = pstrdup(tok);
+ funcname = NULL;
+ }
+
+ initfunc = (func_ptr) load_external_function(filename, funcname, false, NULL);
+ if (initfunc)
+ (*initfunc)();
+
+ elog(LOG, "preloaded library %s with initialization function %s", filename, funcname);
+
+ if (filename != NULL)
+ pfree(filename);
+
+ if (funcname != NULL)
+ pfree(funcname);
+ }
+
+ pfree(rawstring);
+ freeList(elemlist);
+}
+