Bug #30642 Adding the given count to the semaphore would cause it to exceed its maximum cou
Submitted: 27 Aug 2007 9:34 Modified: 14 Apr 2008 20:21
Reporter: Peter Reinhold
Status: Closed
Category:Connector/Net Severity:S2 (Serious)
Version:5.0.8.1 OS:Microsoft Windows (XP SP 2 and 2003 Server)
Assigned to: Target Version:
Tags: Semaphore, pooling, threading

[27 Aug 2007 9:34] Peter Reinhold
Description:
After upgrading from version 5.0.7.0 I have been experiencing a very peculiar bug in my
code.

A trivial SQL query, which has worked without errors, has suddenly begun to throw the
following error

"Adding the given count to the semaphore would cause it to exceed its maximum count"

Nothing in the C# code has been changed, and if I downgrade the MySQL connector to
5.0.7.0 it works fine.

I found the following forum-post on MSDN

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=565516&SiteID=1

and therefore tried disabling pooling by adding a pooling=false to the connectionstring,
but that did not help.

How to repeat:
I haven't yet had the time to try and reproduce this error in a "small" way, which I
would be able to post here, and I am not comfortable posting my entire code here.

But, the program is not very advanced, SQL wise, I run through a list, and for each
entry, I do a fixed amount of selects and inserts.

It looks like the program halts at the same line on every run through, though, which
could point to something being incremented, and not being decreased, and at some point
overflowing.
[27 Aug 2007 11:37] Peter Reinhold
I have done a little more digging, and have got my code working on 5.0.8.1 with some minor
modifications.

Before the change, I had a single MySQL Connector, which I closed, changed
connectionstring on, and then re-opened.

If I changed this so I create a new connection object for each iteration instead, it
works as it should.
[28 Aug 2007 22:04] Reggie Burnett
Peter

Can you give us a bit more info?  Do you run through the loop multiple times or does this
error happen on the first time through?  In what way do you change the connection string? 
Different host?

As much info as possible would be good.  Thx!
[30 Aug 2007 9:27] Tonci Grgin
Peter, what about info Reggie requested?
[30 Aug 2007 9:47] Peter Reinhold
Yes, ofcourse, here's some pseudo-code of when the trouble arised

-- PSEUDOCODE BEGIN --
Create MSCon1
Create MSCon2

Fill MSCon1 with data

Foreach in MSCon1
  If MSCon2 Open Then Close
  Set MSCon2 ConnectionString
  Open MSCon2
  
  Foreach in MSCon2
    DoSomething
  Next

  Close MSCon1
Next

Close MSCon2
-- PSEUDOCODE END --

This was more or less what happened, I did this to re-use the MSCon2 object, and not
spawn a new one for each iteration.

I moved the Create MSCon2 inside the first loop, thus creating a new for each item in
MSCon1, instead of reusing it, and then it worked.

I got the error on the same MSCon1 data-item on each run. (The sixth one)

If i tried changing the way the data was sorted in MSCon1, I got the error on the 10th
item, and it continued to be on the 10th, which was not the same item that threw the
error in the original sort of data (I know this last information may be more confusing
than informative, please let me know if this makes no sense, and i'll try and explain it
better)
[30 Aug 2007 9:49] Peter Reinhold
A little addendum, ofcourse after opening MSCon2, it is filled with data also. (Not really
relevant to the bug, i think)
[17 Sep 2007 8:27] Tonci Grgin
There is a similar error reported in Bug#30816:
 [6 Sep 10:40] Reg Proctor

More information for 5.1.3 (this did not happen in 5.1.2: When I shut down my application
I get the following error:

System.Threading.SemaphoreFullException was unhandled
  Message="Adding the given count to the semaphore would cause it to exceed its maximum
count."
  Source="System"
  StackTrace:
       at System.Threading.Semaphore.Release(Int32 releaseCount)
       at System.Threading.Semaphore.Release()
       at MySql.Data.MySqlClient.MySqlPool.RemoveConnection(Driver driver)
       at MySql.Data.MySqlClient.MySqlPoolManager.RemoveConnection(Driver driver)
       at MySql.Data.MySqlClient.NativeDriver.Dispose(Boolean disposing)
       at MySql.Data.MySqlClient.Driver.Close()
       at MySql.Data.MySqlClient.NativeDriver.Finalize()

Reggie?
[7 Dec 2007 12:27] Tonci Grgin
Peter, I am unable to repeat reported behavior against MySQL server 5.0.54BK on WinXP Pro
SP2 localhost using c/NET 5.0.9.0...

    MySqlConnection conn1 = new MySqlConnection();
    MySqlConnection conn2 = new MySqlConnection();
    MySqlDataReader dr;
    conn1.ConnectionString =
"DataSource=localhost;Database=test;UserID=root;Password=*****;PORT=3306;Allow Zero
Datetime=True;logging=True;";//pooling=true/false does not change anything
    conn1.Open();
    //FAILING CASE, REUSE conn2
    conn2.ConnectionString =
"DataSource=localhost;Database=test;UserID=root;Password=*****;PORT=3306;Allow Zero
Datetime=True;logging=True;";
    conn2.Open();
    MySqlCommand command = new MySqlCommand();
    command.Connection = conn2;
    MySqlDataReader dr2;

    MySqlCommand cmdCreateTable = new MySqlCommand("DROP TABLE IF EXISTS
`test`.`bug30642`", conn1);
    cmdCreateTable.CommandType = CommandType.Text;
    cmdCreateTable.CommandTimeout = 0;
    cmdCreateTable.ExecuteNonQuery();
    cmdCreateTable.CommandText = "CREATE TABLE `test`.`bug30642` (" +
      "`ID` int unsigned NOT NULL AUTO_INCREMENT, " +
      "`LastModified` varchar(50) NOT NULL DEFAULT '', " +
      "PRIMARY KEY (`ID`) " +
      ") DEFAULT CHARSET=latin1;";
    cmdCreateTable.ExecuteNonQuery();
    DateTime dt;
    dt = DateTime.Now;
    cmdCreateTable.CommandText = "INSERT INTO bug30642 VALUES (NULL,'" +
dt.ToString("yyyy-MM-dd HH:mm:ss") + "')";
    try
    {
      Assert.AreEqual(1, cmdCreateTable.ExecuteNonQuery());
      //Add few more rows
      cmdCreateTable.CommandText = "SELECT * FROM bug30642";
      dr = cmdCreateTable.ExecuteReader();
      while (dr.Read())
      {
        Console.WriteLine("READER CONN1: " + dr.GetValue(1).GetType().FullName);
        command.CommandText = "SELECT * FROM bug30642";
        command.CommandType = CommandType.Text;
        dr2 = command.ExecuteReader();
        while (dr2.Read())
        {
          Console.WriteLine("CONN2: "+dr2.GetValue(1).GetType().FullName);
        }
        dr2.Close();
      }
      dr.Close();
      cmdCreateTable.Dispose();
      conn1.Close();
      command.Dispose();
      conn2.Close();
      Console.WriteLine("DONE TESTING");
    }
    catch (Exception ex)
    {
      Assert.Fail(ex.Message);
    }

Output:
[07.12.07 12:21:09] - Executing command QUERY with text ='SELECT * FROM bug30642'
READER CONN1: System.String
READER CONN2: System.String
READER CONN2: System.String
READER CONN2: System.String
READER CONN2: System.String
READER CONN2: System.String
--<cut>--
READER CONN1: System.String
READER CONN2: System.String
READER CONN2: System.String
READER CONN2: System.String
READER CONN2: System.String
READER CONN2: System.String
DONE TESTING
[8 Jan 2008 1:00] Bugs System
No feedback was provided for this bug for over a month, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
[1 Apr 2008 6:37] Damon Overboe
Please clean this up as you see fit, or you may post it to public as is.

using c# 2005, WinXP sp2, MySQL Connector/Net v. 5.2.1

SOLUTION SUMMARY: ensure you are calling explicitly calling disconnect before exiting the
program; my guess is that this error is thrown when the disconnect is called by a
different thread than the one you connect on. 

MY RECREATION:
I have one MySQL class in which I can create and maintain a connection
This class implements the disposable interface and has a destructor, and I have a connect
and disconnect method.

The destructor checks if the class has been disposed, and if not will dispose.
Dispose checks if the connection is closed, and if not will close and dispose.

If I do not explicitly call the disconnect and dispose methods, when the main program
exits, the destructor for the MySQL class fires and starts the series (destructor calls
dispose calls disconnect, then unwinds the stack(disconnect then dispose then destroy)
When it comes to the disconnect command, it throws this same
System.Threading.SemaphoreException error.

MY WORKAROUND / SUMMARY:
I found this error in a test program where I did not properly dispose of my objects. The
workaround for this is that I explicitly call the dispose method to the MySQL class
before the main app exits, and this error is not raised.

Note that when I do this, in respects to the main app, I only call dispose and do not
have to explicitly call the disconnect method in the main app (although my dispose does
call it explicitly).
[14 Apr 2008 20:21] Tonci Grgin
Damon, thanks for your comment. It wouldn't be fair for me to pass it to others so I
decided to just make it public. It may help someone resolve similar issues.

Thanks for your interest in MySQL.
[10 May 2008 21:17] Matt Klein
Hi,

I am seeing this problem again after upgrading from 5.1.5 -> 5.1.6.

Nothing changed in my code. Also, every connection instance is wrapped in a using()
clause which should force the finalizer and the disconnect to happen.

Here is the error trace:

pplication ID: /LM/W3SVC/1977595482/Root

Process ID: 568

Exception: System.Threading.SemaphoreFullException

Message: Adding the given count to the semaphore would cause it to exceed its maximum
count.

StackTrace:    at System.Threading.Semaphore.Release(Int32 releaseCount)
   at System.Threading.Semaphore.Release()
   at MySql.Data.MySqlClient.MySqlPool.RemoveConnection(Driver driver)
   at MySql.Data.MySqlClient.MySqlPoolManager.RemoveConnection(Driver driver)
   at MySql.Data.MySqlClient.NativeDriver.Dispose(Boolean disposing)
   at MySql.Data.MySqlClient.Driver.Close()
   at MySql.Data.MySqlClient.NativeDriver.Finalize()

What can I do to help diagnose this?
[13 May 2008 0:28] Nalle Jacobsson
I'm also seeing this problem after upgrading from 5.1.15 -> 5.1.16
[13 May 2008 0:29] Nalle Jacobsson
Sorry, I meant 5.1.5 -> 5.1.6
[13 May 2008 15:14] Paul Bowden
This problem is also happening to me after upgrading from 5.1.2 -> 5.1.6
[13 May 2008 18:29] Matt Klein
I'm new to the MySQL bug process. It doesn't seem like there is any way to re-activate
this bug. Should a new one be opened?
[15 May 2008 11:38] Tonci Grgin
No need to review anything, if I'm not mistaken, Paul posted Bug#36688 to follow up on
this.
[27 May 2008 23:20] Reggie Burnett
Guys

This issue is the same as 36688 which has been fixed.  We know that 5.1.6 had this bug so
there is no need to keep posting it.
[27 Nov 2008 5:02] Thilina Dampahala
Yes...this bug is there only in MySQL 5.1.6.....I had the above problem...After installing
the version 5.2.6 this matter was solved...

-Thilina Dampahala
[3 Mar 18:14] Pedro Semeano
I'm having the same problem with version 5.1.30...
[3 Mar 18:45] Pedro Semeano
Forget about it... Just installed MySql Connector 6.0 and everything is fine now =)