Bug 830757 - MySQL C API missing THR_KEY_mysys
Summary: MySQL C API missing THR_KEY_mysys
Keywords:
Status: CLOSED WONTFIX
Alias: None
Product: Fedora
Classification: Fedora
Component: mysql
Version: 15
Hardware: All
OS: Linux
unspecified
high
Target Milestone: ---
Assignee: Tom Lane
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2012-06-11 11:02 UTC by Boris Kolpackov
Modified: 2012-08-07 18:58 UTC (History)
2 users (show)

Fixed In Version:
Clone Of:
: 846602 (view as bug list)
Environment:
Last Closed: 2012-08-07 18:58:25 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description Boris Kolpackov 2012-06-11 11:02:29 UTC
Description of problem:

Fedora's build of libmysqlclient hides the THR_KEY_mysys extern variable. This variable contains the thread-specific storage key used by MySQL. ODB (ORM for C++) uses this key to work around issues in automatic MySQL thread initialization/termination (more details below). As a result, ODB fails to compile with Fedora's version of the MySQL client library while working fine with all other distributions (Debian/Ubuntu, SUSELinux) as well as with the MySQL project-provided builds of the library.   

Version-Release number of selected component (if applicable):

MySQL 5.5

How reproducible:

Always.

Steps to Reproduce:

Try to link the following test program:

#include <pthread.h>
extern pthread_key_t THR_KEY_mysys;
int main () {return pthread_getspecific (THR_KEY_mysys) != 0;}

gcc test.c -lmysqlclient_r


Actual results:

/tmp/ccc4WJxN.o: In function `main':
test.c:(.text+0x6): undefined reference to `THR_KEY_mysys'


Expected results:

No errrors.


Additional info:

I realize that this hiding of undocumented symbols is intentional. However, there doesn't seem to be a way to implement automatic thread initialization/termination (mysql_thread_init()/mysql_thread_end() calls for each thread) without access to this key. Here is a more detailed description of what we are doing here:

MySQL requires that each thread that uses the MySQL API first call mysql_thread_init() and at the end call mysql_thread_end(). If the thread fails to call mysql_thread_end(), then MySQL will block the main thread at program termination and wait for this threads to call mysql_thread_end(). If that doesn't happen, then it prints an error message to STDERR. Not a very user-friendly behavior. 

In ODB we are using pthread thread-specific storage to implement automatic handling of this initialization/termination. The idea is basically to call mysql_thread_init() before the first call to the MySQL API and then use the TLS destructor to make sure mysql_thread_end() will get called before the thread exits. This "almost" works without THR_KEY_mysys. The "almost" part comes from this behavior of the Linux pthread implementation (this could also be standard-mandated, I am not sure). When a thread exist the TLS machinery goes over all the TLS slots and calls destructors for those that specified one. Apparently, for those that didn't specify the destructor, it sets the value to zero. So what happens in the case of MySQL is that pthread might set the MySQL TLS slot value to 0 before calling the ODB slot destructor. When ODB destructor calls mysql_thread_end(), MySQL examines its slot value, sees that it is 0,
and ignores the call, assuming this thread has already been terminated or was never initialized.

The only way that we could think of how to resolve this is to cache the MySQL's slot value and then restore it just before calling mysql_thread_end(). And for that we need access to THR_KEY_mysys.

I see that you already export some undocumented/internal functions that are used
by other software (e.g., PHP). I realize this is not ideal, but would it be possible to add THR_KEY_mysys (defined in mysys/my_thr_init.c) to this list?

Comment 1 Tom Lane 2012-06-11 13:02:05 UTC
If you can get upstream to agree that this should be documented as part of their API, I'll be happy to un-hide it.  But without that, relying on it seems like a great way to shoot yourself in the foot.  They have changed undocumented symbols before and doubtless will do so again.  This one is almost certainly not intended to be used by client code ...

Comment 2 Fedora End Of Life 2012-08-07 18:58:27 UTC
This message is a notice that Fedora 15 is now at end of life. Fedora
has stopped maintaining and issuing updates for Fedora 15. It is
Fedora's policy to close all bug reports from releases that are no
longer maintained. At this time, all open bugs with a Fedora 'version'
of '15' have been closed as WONTFIX.

(Please note: Our normal process is to give advanced warning of this
occurring, but we forgot to do that. A thousand apologies.)

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, feel free to reopen
this bug and simply change the 'version' to a later Fedora version.

Bug Reporter: Thank you for reporting this issue and we are sorry that
we were unable to fix it before Fedora 15 reached end of life. If you
would still like to see this bug fixed and are able to reproduce it
against a later version of Fedora, you are encouraged to click on
"Clone This Bug" (top right of this page) and open it against that
version of Fedora.

Although we aim to fix as many bugs as possible during every release's
lifetime, sometimes those efforts are overtaken by events. Often a
more recent Fedora release includes newer upstream software that fixes
bugs or makes them obsolete.

The process we are following is described here:
http://fedoraproject.org/wiki/BugZappers/HouseKeeping


Note You need to log in before you can comment on or make changes to this bug.