From af2808859e7a98666785752b8069c473dda94a1f Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 15 Jun 2012 11:16:44 +0200 Subject: 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. --- odb/mysql/connection-factory.cxx | 37 ++++++++++++++++++++++++------------- odb/mysql/details/config.h.in | 2 ++ odb/mysql/makefile | 1 + 3 files changed, 27 insertions(+), 13 deletions(-) (limited to 'odb') 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_THREADS_* +#include // ODB_THREADS_* +#include // LIBODB_MYSQL_THR_KEY_VISIBLE -#ifdef ODB_THREADS_POSIX +#if defined(ODB_THREADS_POSIX) && defined(LIBODB_MYSQL_THR_KEY_VISIBLE) # include #endif #include // abort +#include +#include + #include #include #include -#include -#include - // 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 */' >>$@ -- cgit v1.1