aboutsummaryrefslogtreecommitdiff
path: root/odb/mysql/connection-factory.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2012-06-15 11:16:44 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-06-15 11:16:44 +0200
commitaf2808859e7a98666785752b8069c473dda94a1f (patch)
tree123979c9700e588ad0f3007c19c096646dd73704 /odb/mysql/connection-factory.cxx
parent5bfec1c98e05b86b719edb37ce1be8778f91d6ec (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.
Diffstat (limited to 'odb/mysql/connection-factory.cxx')
-rw-r--r--odb/mysql/connection-factory.cxx37
1 files changed, 24 insertions, 13 deletions
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 ();
}
};