diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2012-06-15 11:16:44 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2012-06-15 11:16:44 +0200 |
commit | af2808859e7a98666785752b8069c473dda94a1f (patch) | |
tree | 123979c9700e588ad0f3007c19c096646dd73704 | |
parent | 5bfec1c98e05b86b719edb37ce1be8778f91d6ec (diff) |
Add support for building against libmysqlclient that lacks THR_KEY_mysys
In certain distributions (specifically Fedora 15 and later), maintainers
limit the number of visible symbols. If THR_KEY_mysys is hidden, then we
try to create the TLS keys in such an order that it results in the correct
behavior. And then hope for the best.
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | m4/libmysqlclient.m4 | 22 | ||||
-rw-r--r-- | odb/mysql/connection-factory.cxx | 37 | ||||
-rw-r--r-- | odb/mysql/details/config.h.in | 2 | ||||
-rw-r--r-- | odb/mysql/makefile | 1 |
5 files changed, 53 insertions, 13 deletions
diff --git a/configure.ac b/configure.ac index 01cf652..0902700 100644 --- a/configure.ac +++ b/configure.ac @@ -43,6 +43,10 @@ case $libmysqlclient_include in ;; esac +if test x"$libmysqlclient_thr_key_visible" = xyes; then + AC_DEFINE([LIBODB_MYSQL_THR_KEY_VISIBLE], [1], ["THR_KEY_mysys is visible."]) +fi + # Check for libodb. # LIBODB([],[AC_MSG_ERROR([libodb is not found; consider using --with-libodb=DIR])]) diff --git a/m4/libmysqlclient.m4 b/m4/libmysqlclient.m4 index e08a08e..84b4471 100644 --- a/m4/libmysqlclient.m4 +++ b/m4/libmysqlclient.m4 @@ -82,4 +82,26 @@ else AC_MSG_RESULT([no]) $3 fi + +# Check if the THR_KEY_mysys pthread key symbol is visible. +# +libmysqlclient_thr_key_visible=no + +if test x"$libmysqlclient_found" = xyes -a x"$1" = xposix; then + +CXX_LIBTOOL_LINK_IFELSE( +AC_LANG_SOURCE([[ +#include <pthread.h> +extern pthread_key_t THR_KEY_mysys; +int +main () +{ + return pthread_getspecific (THR_KEY_mysys) != 0; +} +]]), +[ +libmysqlclient_thr_key_visible=yes +]) +fi + ])dnl diff --git a/odb/mysql/connection-factory.cxx b/odb/mysql/connection-factory.cxx index ef3647e..cc23de5 100644 --- a/odb/mysql/connection-factory.cxx +++ b/odb/mysql/connection-factory.cxx @@ -2,21 +2,22 @@ // copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file -#include <odb/details/config.hxx> // ODB_THREADS_* +#include <odb/details/config.hxx> // ODB_THREADS_* +#include <odb/mysql/details/config.hxx> // LIBODB_MYSQL_THR_KEY_VISIBLE -#ifdef ODB_THREADS_POSIX +#if defined(ODB_THREADS_POSIX) && defined(LIBODB_MYSQL_THR_KEY_VISIBLE) # include <pthread.h> #endif #include <cstdlib> // abort +#include <odb/details/tls.hxx> +#include <odb/details/lock.hxx> + #include <odb/mysql/mysql.hxx> #include <odb/mysql/connection-factory.hxx> #include <odb/mysql/exceptions.hxx> -#include <odb/details/tls.hxx> -#include <odb/details/lock.hxx> - // This key is in the mysql client library. We use it to resolve the // following problem: Some pthread implementations zero-out slots that // don't have destructors during thread termination. As a result, when @@ -32,7 +33,7 @@ // 1. MySQL doesn't use the destructor itself. // 2. Nobody else tried to call mysql_thread_end() before us. // -#ifdef ODB_THREADS_POSIX +#if defined(ODB_THREADS_POSIX) && defined(LIBODB_MYSQL_THR_KEY_VISIBLE) extern pthread_key_t THR_KEY_mysys; #endif @@ -64,7 +65,7 @@ namespace odb init_ = true; -#ifdef ODB_THREADS_POSIX +#if defined(ODB_THREADS_POSIX) && defined(LIBODB_MYSQL_THR_KEY_VISIBLE) value_ = pthread_getspecific (THR_KEY_mysys); #endif } @@ -74,7 +75,7 @@ namespace odb { if (init_) { -#ifdef ODB_THREADS_POSIX +#if defined(ODB_THREADS_POSIX) && defined(LIBODB_MYSQL_THR_KEY_VISIBLE) if (pthread_getspecific (THR_KEY_mysys) == 0) pthread_setspecific (THR_KEY_mysys, value_); #endif @@ -84,7 +85,7 @@ namespace odb private: bool init_; -#ifdef ODB_THREADS_POSIX +#if defined(ODB_THREADS_POSIX) && defined(LIBODB_MYSQL_THR_KEY_VISIBLE) void* value_; #endif #endif // ODB_THREADS_NONE @@ -96,21 +97,31 @@ namespace odb { mysql_process_init () { - if (mysql_library_init (0 ,0, 0)) - abort (); - + // Force allocation of our thread-specific key before THR_KEY_mysys + // in MySQL. This will (hopefully) get us the desired order of TLS + // destructor calls (i.e., our destructor before zeroing-out the + // THR_KEY_mysys value). This is pretty much the only way (except + // maybe guessing the THR_KEY_mysys value) to get clean thread + // termination if THR_KEY_mysys symbol is hidden, as is the case + // in the Fedora build of libmysqlclient. See also the comment + // at the beginning of this file. + // main_thread_init_ = true; tls_get (mysql_thread_init_); main_thread_init_ = false; + + if (mysql_library_init (0 ,0, 0)) + abort (); } ~mysql_process_init () { + mysql_library_end (); + // Finalize the main thread now in case TLS destruction // doesn't happen for the main thread. // tls_free (mysql_thread_init_); - mysql_library_end (); } }; diff --git a/odb/mysql/details/config.h.in b/odb/mysql/details/config.h.in index 8231ed8..6f70c3e 100644 --- a/odb/mysql/details/config.h.in +++ b/odb/mysql/details/config.h.in @@ -13,4 +13,6 @@ #undef LIBODB_MYSQL_INCLUDE_SHORT #undef LIBODB_MYSQL_INCLUDE_LONG +#undef LIBODB_MYSQL_THR_KEY_VISIBLE + #endif /* ODB_MYSQL_DETAILS_CONFIG_H */ diff --git a/odb/mysql/makefile b/odb/mysql/makefile index 1b14f60..4ae255f 100644 --- a/odb/mysql/makefile +++ b/odb/mysql/makefile @@ -80,6 +80,7 @@ $(out_base)/details/config.h: | $(out_base)/details/. @echo '#define ODB_MYSQL_DETAILS_CONFIG_H' >>$@ @echo '' >>$@ @echo '#define LIBODB_MYSQL_INCLUDE_LONG 1' >>$@ + @echo '#define LIBODB_MYSQL_THR_KEY_VISIBLE 1' >>$@ @echo '' >>$@ @echo '#endif /* ODB_MYSQL_DETAILS_CONFIG_H */' >>$@ |