| Bug #13099 | multithreaded client app hits race condition in my_init() | ||
|---|---|---|---|
| Submitted: | 10 Sep 2005 5:20 | Modified: | 14 Jun 2013 16:16 |
| Reporter: | Timothy Smith | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server | Severity: | S4 (Feature request) |
| Version: | all | OS: | Any (all) |
| Assigned to: | Matthew Lord | CPU Architecture: | Any |
[5 May 2006 7:46]
Konstantin Osipov
This is a documented limitation of our client library: in a multithreaded application, one should invoke mysql_library_init prior to any other library function call. This report is a valid feature request but by no means can be fixed in a GA release - we need to implement pthread_once support on Windows and netware in order to make the client library 100% thread safe. Please do not use undocumented API in client applications - they are a subject to change. my_init is removed from client library headers in 5.1. See http://dev.mysql.com/doc/refman/5.0/en/c-api-function-overview.html for details. PS The documentation says "If you like, the call to mysql_library_init() may be omitted, because mysql_init() will invoke it automatically as necessary." I will now file a docs request to clarify that if mysql_library_init is invoked by mysql_init in a multithreaded environment, a race condition is possible: mysql_library_init is not thread-safe and should be called prior to any other client library call in a multithreaded environment. I will also ask the documentation team to clarify this in the documentation section for mysql_library_init.
[15 Mar 2007 18:30]
Jeffrey Pugh
Architecture Board meeting today agreed that this is not a bug because it works as documented. However it *is* a usability issue that should be addressed by better documentation and redesign of client API.
[14 Jun 2013 16:16]
Matthew Lord
Hi Tim! Thank you for the bug report. I'm closing this old FR/bug report now, as we try and call my_init() automatically now when making various calls such as mysql_connect(): http://dev.mysql.com/doc/refman/5.6/en/my-init.html If you feel that there's still a relevant FR that you would like to make here, please let me know. Thanks again!

Description: The code with the race is in mysys/my_init.c: my_bool my_init(void) { my_string str; if (my_init_done) /* Here's the race condition */ return 0; my_init_done=1; mysys_usage_id++; Our current policy is just that the application must call mysql_library_init() before calling any other MySQL functions, in order to avoid this problem. But that is inconvenient, error prone, and sometimes not feasible in large-scale projects. A solution is to use pthread_once(), to only call my_init(). How to repeat: Imagine there is a sleep(10) call before the my_init_done=1 assignment in the above code. Imagine that two threads call my_init() at the same time. Imagine them both executing the my_init() code. Suggested fix: It looks like there is a way to implement pthread_once() on Windows via atomic addition. Once that is taken care of, pthread_once can be used without portability problems. It should then be an easy fix to only call my_init once. Thanks, Timothy