Bug #2268 mysql_once_init() doesn't call my_thead_init() the first time
Submitted: 3 Jan 2004 9:16 Modified: 14 Jan 2004 16:37
Reporter: Barry Muirhead Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server Severity:S3 (Non-critical)
Version:4.0.13 (and 4.1 at first glance) OS:
Assigned to: Dean Ellis CPU Architecture:Any

[3 Jan 2004 9:16] Barry Muirhead
Description:
When threads are enabled, my_thread_init() must be called for each thread.  The documentation says that mysql_real_connect() will do so.  But mysql_real_connect() only calls mysql_once_init(), which I believe mistakenly doesn't call my_thread_init()on the first (once) call.

How to repeat:
NA

Suggested fix:
Remove the "else" before the my_thread_init()in mysql_once_init() (in libmysql.c).
[3 Jan 2004 10:41] Barry Muirhead
The previous description refers to mysql_real_connect(), but should have refered to mysql_connect() (or mysql_init() ).
[6 Jan 2004 8:44] Dean Ellis
mysql_once_init() will call my_init() (because mysql_client_init == 0), which will in turn call my_thread_global_init() which calls my_thread_init(), so it would appear that my_thread_init() is called on every call to mysql_once_init().

If you are seeing something else, please let me know.
[6 Jan 2004 16:08] Barry Muirhead
my_init() doesn't necessarily call my_thread_global_init();  only if it hasn't been called before.  So if one thread calls my_init(), and another calls mysql_once_init(), the later thread is not inited.

When I removed my code's call to my_init(), the crash (which is a result of thread not being inited) happens much less frequently.  But it still occurs.  I haven't determined the exact mechanism, but it must be a race;  I have a number of threads trying their initial connect to the dbs at program startup time.

So I see that removing the "else" in mysql_once_init() is not the ideal solution, but it does appear to solve the problem.
[7 Jan 2004 6:57] Dean Ellis
Can you submit a test case demonstrating your issue?  Noting that my_init() does not need to be called multiple times (or called explicitly at all in some cases), and you should generally have no reason to call mysql_once_init() directly, I think it would be simplest to see code which identifies your problem.
[7 Jan 2004 8:39] Barry Muirhead
Here is code that demonstrates the problem:

in thread 1:
  my_init();

in thread 2:
  mysql_init(&mysql);

if thread 1 executes before thread 2, mysql_thread_init()is clearly not performed for thread 2.  So I think you should reclassify this a bug.

In addition, when I remove my only explicit call to my_init(), I still occasionally experience an uninitialized thread when many threads are calling mysql_init()"simultaneously". I haven't found the mechanism that causes this, but my temporary "fix" (removing the "else" in mysql_once_init()) seems to work here too.
[14 Jan 2004 16:37] Dean Ellis
The flow you are seeing is because my_init() has already been completed, so in the subsequent thread it simply returns without performing the thread initializations.

With that said, however, I am thinking this should remain "Not a Bug" because the documentation essentially covers this issue already.  The description for the mysql_thread_init() function states that it needs to be called for each thread.  The "How to Make a Threaded Client" chapter also mentions this.

You do not explicitly call mysql_thread_init() in the pseudocode above; is this the case for your actual program?