From 4848d634fa214c19c4fbfcb5c8350194a029d3f9 Mon Sep 17 00:00:00 2001 From: wrowe Date: Fri, 21 Nov 2008 06:30:43 +0000 Subject: Introduce DBM DSO linkage. git-svn-id: http://svn.apache.org/repos/asf/apr/apr-util/trunk@719504 13f79535-47bb-0310-9956-ffa450edef68 --- Makefile.in | 3 + build.conf | 21 +++- build/dbm.m4 | 24 ++--- build/dso.m4 | 10 +- dbm/apr_dbm.c | 198 +++++++++++++++++++++++++++----------- dbm/apr_dbm_berkeleydb.c | 2 +- dbm/apr_dbm_gdbm.c | 2 +- dbm/apr_dbm_ndbm.c | 2 +- include/private/apr_dbm_private.h | 6 +- 9 files changed, 189 insertions(+), 79 deletions(-) diff --git a/Makefile.in b/Makefile.in index 305d3302..963feada 100644 --- a/Makefile.in +++ b/Makefile.in @@ -37,6 +37,9 @@ LDADD_dbd_sqlite3 = @LDADD_dbd_sqlite3@ LDADD_dbd_mysql = @LDADD_dbd_mysql@ LDADD_dbd_freetds = @LDADD_dbd_freetds@ LDADD_dbd_odbc = @LDADD_dbd_odbc@ +LDADD_dbm_db = @LDADD_dbm_db@ +LDADD_dbm_gdbm = @LDADD_dbm_gdbm@ +LDADD_dbm_ndbm = @LDADD_dbm_ndbm@ LDADD_ldap = @LDADD_ldap@ LDADD_crypto_openssl = @LDADD_crypto_openssl@ LDADD_crypto_nss = @LDADD_crypto_nss@ diff --git a/build.conf b/build.conf index c7cb90a1..226aabe3 100644 --- a/build.conf +++ b/build.conf @@ -13,7 +13,8 @@ paths = crypto/apr_sha1.c crypto/getuuid.c crypto/uuid.c - dbm/*.c + dbm/apr_dbm_sdbm.c + dbm/apr_dbm.c dbm/sdbm/*.c encoding/*.c hooks/*.c @@ -33,7 +34,10 @@ platform_dirs = # the public headers headers = include/*.h include/private/*.h -modules = crypto_openssl crypto_nss ldap dbd_pgsql dbd_sqlite2 dbd_sqlite3 dbd_oracle dbd_mysql dbd_freetds dbd_odbc +modules = + ldap crypto_openssl crypto_nss dbd_pgsql + dbd_sqlite2 dbd_sqlite3 dbd_oracle dbd_mysql dbd_freetds dbd_odbc + dbm_db dbm_gdbm dbm_ndbm # gen_uri_delim.c @@ -76,8 +80,21 @@ target = dbd/apr_dbd_freetds.la paths = dbd/apr_dbd_odbc.c target = dbd/apr_dbd_odbc.la +[dbm_db] +paths = dbm/apr_dbm_berkeleydb.c +target = dbm/apr_dbm_db.la + +[dbm_gdbm] +paths = dbm/apr_dbm_gdbm.c +target = dbm/apr_dbm_gdbm.la + +[dbm_ndbm] +paths = dbm/apr_dbm_ndbm.c +target = dbm/apr_dbm_ndbm.la + [ldap] paths = ldap/apr_ldap_init.c \ ldap/apr_ldap_option.c \ ldap/apr_ldap_rebind.c target = ldap/apr_ldap.la + diff --git a/build/dbm.m4 b/build/dbm.m4 index 6998eee3..c4c8afb9 100644 --- a/build/dbm.m4 +++ b/build/dbm.m4 @@ -911,25 +911,25 @@ AC_DEFUN([APU_CHECK_DBM], [ AC_SUBST(apu_db_header) AC_SUBST(apu_db_version) + if test "$apu_have_db" = "1"; then + LDADD_dbm_db="-l$apu_db_lib" + if test -n "apu_db_xtra_libs"; then + LDADD_dbm_db="$LDADD_dbm_db $apu_db_xtra_libs" + fi + fi + dnl Since we have already done the AC_CHECK_LIB tests, if we have it, dnl we know the library is there. if test "$apu_have_gdbm" = "1"; then - APR_ADDTO(APRUTIL_EXPORT_LIBS,[-lgdbm]) - APR_ADDTO(APRUTIL_LIBS,[-lgdbm]) + LDADD_dbm_gdbm="-lgdbm" fi if test "$apu_have_ndbm" = "1"; then - APR_ADDTO(APRUTIL_EXPORT_LIBS,[-l$apu_ndbm_lib]) - APR_ADDTO(APRUTIL_LIBS,[-l$apu_ndbm_lib]) + LDADD_dbm_ndbm="-l$apu_ndbm_lib" fi - if test "$apu_have_db" = "1"; then - APR_ADDTO(APRUTIL_EXPORT_LIBS,[-l$apu_db_lib]) - APR_ADDTO(APRUTIL_LIBS,[-l$apu_db_lib]) - if test -n "apu_db_xtra_libs"; then - APR_ADDTO(APRUTIL_EXPORT_LIBS,[$apu_db_xtra_libs]) - APR_ADDTO(APRUTIL_LIBS,[$apu_db_xtra_libs]) - fi - fi + AC_SUBST(LDADD_dbm_db) + AC_SUBST(LDADD_dbm_gdbm) + AC_SUBST(LDADD_dbm_ndbm) ]) diff --git a/build/dso.m4 b/build/dso.m4 index 0e9efc7e..beec1bec 100644 --- a/build/dso.m4 +++ b/build/dso.m4 @@ -22,7 +22,7 @@ AC_DEFUN([APU_CHECK_UTIL_DSO], [ AC_ARG_ENABLE([util-dso], APR_HELP_STRING([--disable-util-dso], - [disable DSO build of modular components (crypto, dbd, ldap)])) + [disable DSO build of modular components (crypto, dbd, dbm, ldap)])) if test "$enable_util_dso" = "no"; then apu_dso_build="0" @@ -44,6 +44,9 @@ AC_DEFUN([APU_CHECK_UTIL_DSO], [ test $apu_have_sqlite3 = 1 && objs="$objs dbd/apr_dbd_sqlite3.lo" test $apu_have_freetds = 1 && objs="$objs dbd/apr_dbd_freetds.lo" test $apu_have_odbc = 1 && objs="$objs dbd/apr_dbd_odbc.lo" + test $apu_have_db = 1 && objs="$objs dbm/apr_dbm_berkeleydb.lo" + test $apu_have_gdbm = 1 && objs="$objs dbm/apr_dbm_gdbm.lo" + test $apu_have_ndbm = 1 && objs="$objs dbm/apr_dbm_ndbm.lo" test $apu_has_ldap = 1 && objs="$objs ldap/apr_ldap_init.lo" test $apu_has_ldap = 1 && objs="$objs ldap/apr_ldap_option.lo" test $apu_has_ldap = 1 && objs="$objs ldap/apr_ldap_rebind.lo" @@ -65,9 +68,11 @@ AC_DEFUN([APU_CHECK_UTIL_DSO], [ APRUTIL_LIBS="$APRUTIL_LIBS $LDADD_crypto_openssl $LDADD_crypto_nss" APRUTIL_LIBS="$APRUTIL_LIBS $LDADD_dbd_pgsql $LDADD_dbd_sqlite2 $LDADD_dbd_sqlite3 $LDADD_dbd_oracle $LDADD_dbd_mysql $LDADD_dbd_freetds $LDADD_dbd_odbc" + APRUTIL_LIBS="$APRUTIL_LIBS $LDADD_dbm_db $LDADD_dbm_gdbm $LDADD_dbm_ndbm" APRUTIL_LIBS="$APRUTIL_LIBS $LDADD_ldap" APRUTIL_EXPORT_LIBS="$APRUTIL_EXPORT_LIBS $LDADD_crypto_openssl $LDADD_crypto_nss" APRUTIL_EXPORT_LIBS="$APRUTIL_EXPORT_LIBS $LDADD_dbd_pgsql $LDADD_dbd_sqlite2 $LDADD_dbd_sqlite3 $LDADD_dbd_oracle $LDADD_dbd_mysql $LDADD_dbd_freetds $LDADD_dbd_odbc" + APRUTIL_EXPORT_LIBS="$APRUTIL_EXPORT_LIBS $LDADD_dbm_db $LDADD_dbm_gdbm $LDADD_dbm_ndbm" APRUTIL_EXPORT_LIBS="$APRUTIL_EXPORT_LIBS $LDADD_ldap" else @@ -83,6 +88,9 @@ AC_DEFUN([APU_CHECK_UTIL_DSO], [ test $apu_have_sqlite3 = 1 && dsos="$dsos dbd/apr_dbd_sqlite3.la" test $apu_have_freetds = 1 && dsos="$dsos dbd/apr_dbd_freetds.la" test $apu_have_odbc = 1 && dsos="$dsos dbd/apr_dbd_odbc.la" + test $apu_have_db = 1 && dsos="$dsos dbm/apr_dbm_db.la" + test $apu_have_gdbm = 1 && dsos="$dsos dbm/apr_dbm_gdbm.la" + test $apu_have_ndbm = 1 && dsos="$dsos dbm/apr_dbm_ndbm.la" test $apu_has_ldap = 1 && dsos="$dsos ldap/apr_ldap.la" if test -n "$dsos"; then diff --git a/dbm/apr_dbm.c b/dbm/apr_dbm.c index d4fed7b1..04b517b5 100644 --- a/dbm/apr_dbm.c +++ b/dbm/apr_dbm.c @@ -24,6 +24,7 @@ #include "apr_general.h" #include "apu.h" +#include "apr_dbm_private.h" #include "apu_select_dbm.h" #include "apr_dbm.h" #include "apr_dbm_private.h" @@ -34,56 +35,165 @@ ### API entirely? Oh, what to do. We need an APU_DEFAULT_DBM #define. ### Sounds like a job for autoconf. */ -#if APU_USE_SDBM -#define DBM_VTABLE apr_dbm_type_sdbm +#if APU_USE_DB +#define DBM_VTABLE apr_dbm_type_db +#define DBM_NAME "db" #elif APU_USE_GDBM #define DBM_VTABLE apr_dbm_type_gdbm -#elif APU_USE_DB -#define DBM_VTABLE apr_dbm_type_db +#define DBM_NAME "gdbm" #elif APU_USE_NDBM #define DBM_VTABLE apr_dbm_type_ndbm +#define DBM_NAME "ndbm" +#elif APU_USE_SDBM +#define DBM_VTABLE apr_dbm_type_sdbm +#define DBM_NAME "sdbm" #else /* Not in the USE_xDBM list above */ #error a DBM implementation was not specified #endif -APU_DECLARE(apr_status_t) apr_dbm_open_ex(apr_dbm_t **pdb, const char*type, - const char *pathname, - apr_int32_t mode, apr_fileperms_t perm, - apr_pool_t *pool) +#ifdef APU_DSO_BUILD + +static apr_hash_t *drivers = NULL; + +static apr_status_t apr_dbd_term(void *ptr) { + /* set drivers to NULL so init can work again */ + drivers = NULL; + + /* Everything else we need is handled by cleanups registered + * when we created mutexes and loaded DSOs + */ + return APR_SUCCESS; +} + +#endif /* APU_DSO_BUILD */ + +static apr_status_t dbm_open_type(apr_dbm_type_t const* * vtable, + const char *type, + apr_pool_t *pool) +{ +#ifndef APU_DSO_BUILD + + *vtable = NULL; + if (!strcasecmp(type, "default")) *vtable = &DBM_VTABLE; +#if APU_HAVE_DB + else if (!strcasecmp(type, "db")) *vtable = &apr_dbm_type_db; +#endif + else if (*type && !strcasecmp(type + 1, "dbm")) { #if APU_HAVE_GDBM - if (!strcasecmp(type, "GDBM")) { - return (*apr_dbm_type_gdbm.open)(pdb, pathname, mode, perm, pool); - } + if (*type == 'G' && *type == 'g') *vtable = &apr_dbm_type_gdbm; +#endif +#if APU_HAVE_NDBM + if (*type == 'N' && *type == 'n') *vtable = &apr_dbm_type_ndbm; #endif #if APU_HAVE_SDBM - if (!strcasecmp(type, "SDBM")) { - return (*apr_dbm_type_sdbm.open)(pdb, pathname, mode, perm, pool); - } + if (*type == 'S' && *type == 's') *vtable = &apr_dbm_type_sdbm; #endif -#if APU_HAVE_DB - if (!strcasecmp(type, "DB")) { - return (*apr_dbm_type_db.open)(pdb, pathname, mode, perm, pool); + /* avoid empty block */ ; } -#endif -#if APU_HAVE_NDBM - if (!strcasecmp(type, "NDBM")) { - return (*apr_dbm_type_ndbm.open)(pdb, pathname, mode, perm, pool); + if (*vtable) + return APR_SUCCESS; + return APR_ENOTIMPL; + +#else /* APU_DSO_BUILD */ + + char modname[32]; + char symname[34]; + apr_dso_handle_sym_t symbol; + apr_status_t rv; + int usertype = 0; + + if (!strcasecmp(type, "default")) type = DBM_NAME; + else if (!strcasecmp(type, "db")) type = "db"; + else if (*type && !strcasecmp(type + 1, "dbm")) { + if (type == 'G' || type == 'g') type = "gdbm"; + else if (type == 'N' || type == 'n') type = "ndbm"; + else if (type == 'S' || type == 's') type = "sdbm"; + } + else usertype = 1; + + if (!drivers) + { + apr_pool_t *ppool = pool; + apr_pool_t *parent; + + /* Top level pool scope, need process-scope lifetime */ + for (parent = pool; parent; parent = apr_pool_parent_get(ppool)) + ppool = parent; + + /* deprecate in 2.0 - permit implicit initialization */ + apu_dso_init(ppool); + + drivers = apr_hash_make(ppool); + apr_hash_set(drivers, "sdbm", APR_HASH_KEY_STRING, &apr_dbm_type_sdbm); + + apr_pool_cleanup_register(ppool, NULL, dbm_term, + apr_pool_cleanup_null); } + + rv = apu_dso_mutex_lock(); + if (rv) { + *vtable = NULL + return rv; + } + + *vtable = apr_hash_get(drivers, type, APR_HASH_KEY_STRING); + if (*vtable) { + apu_dso_mutex_unlock(); + return APR_SUCCESS; + } + + /* The driver DSO must have exactly the same lifetime as the + * drivers hash table; ignore the passed-in pool */ + pool = apr_hash_pool_get(drivers); + +#if defined(NETWARE) + apr_snprintf(modname, sizeof(modname), "dbm%s.nlm", type); +#elif defined(WIN32) + apr_snprintf(modname, sizeof(modname), + "apr_dbm_%s-" APU_STRINGIFY(APU_MAJOR_VERSION) ".dll", type); +#else + apr_snprintf(modname, sizeof(modname), + "apr_dbm_%s-" APU_STRINGIFY(APU_MAJOR_VERSION) ".so", type); #endif + apr_snprintf(symname, sizeof(symname), "apr_dbm_type_%s", type); - if (!strcasecmp(type, "default")) { - return (*DBM_VTABLE.open)(pdb, pathname, mode, perm, pool); + rv = apu_dso_load(&symbol, modname, symname, pool); + if (rv != APR_SUCCESS || rv == APR_EINIT) { /* previously loaded?!? */ + *vtable = symbol; + if (usertype) + type = apr_pstrdup(pool, type); + apr_hash_set(drivers, type, APR_HASH_KEY_STRING, *vtable); } + else + *vtable = NULL; - return APR_ENOTIMPL; + apu_dso_mutex_unlock(); + return rv; + +#endif /* APU_DSO_BUILD */ +} + +APU_DECLARE(apr_status_t) apr_dbm_open_ex(apr_dbm_t **pdb, const char *type, + const char *pathname, + apr_int32_t mode, + apr_fileperms_t perm, + apr_pool_t *pool) +{ + apr_dbm_type_t const* vtable = NULL; + apr_status_t rv = dbm_open_type(&vtable, type, pool); + + if (rv == APR_SUCCESS) { + rv = (vtable->open)(pdb, pathname, mode, perm, pool); + } + return rv; } APU_DECLARE(apr_status_t) apr_dbm_open(apr_dbm_t **pdb, const char *pathname, apr_int32_t mode, apr_fileperms_t perm, apr_pool_t *pool) { - return (*DBM_VTABLE.open)(pdb, pathname, mode, perm, pool); + return apr_dbm_open_ex(pdb, DBM_NAME, pathname, mode, perm, pool); } APU_DECLARE(void) apr_dbm_close(apr_dbm_t *dbm) @@ -149,37 +259,14 @@ APU_DECLARE(apr_status_t) apr_dbm_get_usednames_ex(apr_pool_t *p, const char **used1, const char **used2) { -#if APU_HAVE_GDBM - if (!strcasecmp(type, "GDBM")) { - (*apr_dbm_type_gdbm.getusednames)(p,pathname,used1,used2); - return APR_SUCCESS; - } -#endif -#if APU_HAVE_SDBM - if (!strcasecmp(type, "SDBM")) { - (*apr_dbm_type_sdbm.getusednames)(p,pathname,used1,used2); - return APR_SUCCESS; - } -#endif -#if APU_HAVE_DB - if (!strcasecmp(type, "DB")) { - (*apr_dbm_type_db.getusednames)(p,pathname,used1,used2); - return APR_SUCCESS; - } -#endif -#if APU_HAVE_NDBM - if (!strcasecmp(type, "NDBM")) { - (*apr_dbm_type_ndbm.getusednames)(p,pathname,used1,used2); - return APR_SUCCESS; - } -#endif + apr_dbm_type_t const* vtable; + apr_status_t rv = dbm_open_type(&vtable, type, p); - if (!strcasecmp(type, "default")) { - (*DBM_VTABLE.getusednames)(p, pathname, used1, used2); + if (rv == APR_SUCCESS) { + (vtable->getusednames)(p, pathname, used1, used2); return APR_SUCCESS; } - - return APR_ENOTIMPL; + return rv; } APU_DECLARE(void) apr_dbm_get_usednames(apr_pool_t *p, @@ -187,10 +274,7 @@ APU_DECLARE(void) apr_dbm_get_usednames(apr_pool_t *p, const char **used1, const char **used2) { - /* ### one day, a DBM type name will be passed and we'll need to look it - ### up. for now, it is constant. */ - - (*DBM_VTABLE.getusednames)(p, pathname, used1, used2); + apr_dbm_get_usednames_ex(p, DBM_NAME, pathname, used1, used2); } /* Most DBM libraries take a POSIX mode for creating files. Don't trust diff --git a/dbm/apr_dbm_berkeleydb.c b/dbm/apr_dbm_berkeleydb.c index 06277421..00b47467 100644 --- a/dbm/apr_dbm_berkeleydb.c +++ b/dbm/apr_dbm_berkeleydb.c @@ -385,7 +385,7 @@ static void vt_db_usednames(apr_pool_t *pool, const char *pathname, } -APU_DECLARE_DATA const apr_dbm_type_t apr_dbm_type_db = { +APU_MODULE_DECLARE_DATA const apr_dbm_type_t apr_dbm_type_db = { "db", vt_db_open, diff --git a/dbm/apr_dbm_gdbm.c b/dbm/apr_dbm_gdbm.c index e5462c47..87c0ac72 100644 --- a/dbm/apr_dbm_gdbm.c +++ b/dbm/apr_dbm_gdbm.c @@ -237,7 +237,7 @@ static void vt_gdbm_usednames(apr_pool_t *pool, const char *pathname, *used2 = NULL; } -APU_DECLARE_DATA const apr_dbm_type_t apr_dbm_type_gdbm = { +APU_MODULE_DECLARE_DATA const apr_dbm_type_t apr_dbm_type_gdbm = { "gdbm", vt_gdbm_open, vt_gdbm_close, diff --git a/dbm/apr_dbm_ndbm.c b/dbm/apr_dbm_ndbm.c index 42ddbed3..db6eec1f 100644 --- a/dbm/apr_dbm_ndbm.c +++ b/dbm/apr_dbm_ndbm.c @@ -220,7 +220,7 @@ static void vt_ndbm_usednames(apr_pool_t *pool, const char *pathname, *used2 = NULL; } -APU_DECLARE_DATA const apr_dbm_type_t apr_dbm_type_ndbm = { +APU_MODULE_DECLARE_DATA const apr_dbm_type_t apr_dbm_type_ndbm = { "ndbm", vt_ndbm_open, vt_ndbm_close, diff --git a/include/private/apr_dbm_private.h b/include/private/apr_dbm_private.h index c598752f..1c23c13d 100644 --- a/include/private/apr_dbm_private.h +++ b/include/private/apr_dbm_private.h @@ -110,13 +110,11 @@ struct apr_dbm_t /* Declare all of the builtin DBM providers */ APU_DECLARE_DATA extern const apr_dbm_type_t apr_dbm_type_sdbm; +#if !APU_DSO_BUILD APU_DECLARE_DATA extern const apr_dbm_type_t apr_dbm_type_gdbm; APU_DECLARE_DATA extern const apr_dbm_type_t apr_dbm_type_ndbm; -APU_DECLARE_DATA extern const apr_dbm_type_t apr_dbm_type_db1; -APU_DECLARE_DATA extern const apr_dbm_type_t apr_dbm_type_db2; -APU_DECLARE_DATA extern const apr_dbm_type_t apr_dbm_type_db3; -APU_DECLARE_DATA extern const apr_dbm_type_t apr_dbm_type_db4; APU_DECLARE_DATA extern const apr_dbm_type_t apr_dbm_type_db; +#endif #ifdef __cplusplus } -- cgit v1.2.1