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:
None 
Category:MySQL Server Severity:S4 (Feature request)
Version:all OS:Any (all)
Assigned to: Matthew Lord CPU Architecture:Any

[10 Sep 2005 5:20] Timothy Smith
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
[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!