Bug #17106 MySql.Data.MySqlClient.CharSetMap.GetEncoding thread synchronization issue
Submitted: 3 Feb 2006 20:22 Modified: 4 Jun 2006 4:11
Reporter: Frank Vera Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / NET Severity:S3 (Non-critical)
Version:1.0.7.30072 OS:Microsoft Windows (Windows 2003 Server)
Assigned to: Reggie Burnett CPU Architecture:Any

[3 Feb 2006 20:22] Frank Vera
Description:
Under ASP.NET the following errors (among many others) occur if multiple threads try to call MySqlConnection.Open concurrently:

System.ArgumentException: Item has already been added.  Key in dictionary: "gb2312"  Key being added: "gb2312"
   at System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add)
   at System.Collections.Hashtable.Add(Object key, Object value)
   at MySql.Data.MySqlClient.CharSetMap.LoadCharsetMap()
   at MySql.Data.MySqlClient.CharSetMap.GetEncoding(DBVersion version, String CharSetName)
   at MySql.Data.MySqlClient.Driver.Configure(MySqlConnection connection)
   at MySql.Data.MySqlClient.NativeDriver.Configure(MySqlConnection connection)
   at MySql.Data.MySqlClient.MySqlConnection.Open()

MySql.Data.MySqlClient.MySqlException: Character set 'latin1' is not supported
   at MySql.Data.MySqlClient.CharSetMap.GetEncoding(DBVersion version, String CharSetName)
   at MySql.Data.MySqlClient.Driver.Configure(MySqlConnection connection)
   at MySql.Data.MySqlClient.NativeDriver.Configure(MySqlConnection connection)
   at MySql.Data.MySqlClient.MySqlConnection.Open()
   
System.ArgumentException: Item has already been added.  Key in dictionary: "latin4"  Key being added: "latin4"
   at System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add)
   at System.Collections.Hashtable.Add(Object key, Object value)
   at MySql.Data.MySqlClient.CharSetMap.LoadCharsetMap()
   at MySql.Data.MySqlClient.CharSetMap.GetEncoding(DBVersion version, String CharSetName)
   at MySql.Data.MySqlClient.Driver.Configure(MySqlConnection connection)
   at MySql.Data.MySqlClient.NativeDriver.Configure(MySqlConnection connection)
   at MySql.Data.MySqlClient.MySqlConnection.Open()

The problem seems to be in: MySql.Data.MySqlClient.CharSetMap.GetEncoding

			if (mapping == null )
				InitializeMapping();

How to repeat:
Can only be repeated if multiple threads call MySqlConnection.Open() at the same time.

Suggested fix:

Please move the InitializeMapping call into a static constructor which is guaranteed to be thread safe:

static CharSetMap()
{
   InitializeMapping();   
}

or (more expensive) 

public static Encoding GetEncoding( DBVersion version, string CharSetName ) 
{
   lock(typeof(CharSetMap))
   {
      if (mapping == null )
         InitializeMapping();
   }
   ...
}
[26 May 2006 18:14] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/6917
[1 Jun 2006 18:38] Reggie Burnett
fixed in 1.0.8
[4 Jun 2006 4:11] MC Brown
Documented in the changelog.