Bug #33682 Patch: Semaphore class is Windows only preventing mono from using connector
Submitted: 3 Jan 2008 23:16 Modified: 8 Jul 2008 14:09
Reporter: Andrew A Email Updates:
Status: Closed Impact on me:
Category:Connector / NET Severity:S1 (Critical)
Version:1.0.10+ OS:Linux
Assigned to: CPU Architecture:Any
Tags: connector, Contribution, Mono, pooling, Semaphore

[3 Jan 2008 23:16] Andrew A
Attempting to utilize MySQL Connector .Net version 1.0.10 (.Net 1.1 framework) or later throws a fatal exception under mono when pooling is enabled.

This is due to the use of a Semaphore class which imports its routines for handling the synchronization from an external library, kernel32.dll, found only on Windows which is used by the MysqlPool class.

This problem does not occur if pooling is disabled.

A stack trace after calling Open() on a single MySql connection appears as follows:
Unhandled Exception: System.DllNotFoundException: kernel32.dll
in (wrapper managed-to-native) MySql.Data.Common.Semaphore:CreateSemaphore (MySql.Data.Common.SECURITY_ATTRIBUTES&,int,int,string)
in <0x00040> MySql.Data.Common.Semaphore:.ctor (Int32 initialCount, Int32 maximumCount)
in (wrapper remoting-invoke-with-check) MySql.Data.Common.Semaphore:.ctor (int,int)
in <0x000ee> MySql.Data.MySqlClient.MySqlPool:.ctor (MySql.Data.MySqlClient.MySqlConnectionString settings)
in <0x0008a> MySql.Data.MySqlClient.MySqlPoolManager:GetPool (MySql.Data.MySqlClient.MySqlConnectionString settings)
in <0x00055> MySql.Data.MySqlClient.MySqlConnection:Open ()

How to repeat:
Run any project that utilizes MySQL pooling (pooling = true in the connection string) and wait for a single connection to be opened.

A stack trace immediately follows under mono.

At the time of writing this was tested on the latest releases of Mono and MySQL .Net Connector:
Mono JIT compiler version 1.2.6 (tarball)
MySQL .Net Connector 1.0.10

This problem was introduced by Commit 20420 (Bug #24373 High CPU utilization when no idle connection).

A simple test case has been attached which reproduces the problem.

Replace the implementation of mysqlclient/common/Semaphore.cs which makes use of kernel32.dll with a pure managed code version of the class.

Suggested fix:
I have attached my own version of the Semaphore class I have created as well as a new test case.

This fix implements a basic Semaphore class that has the functionality used by the current MySQL Pooling class only.
[3 Jan 2008 23:18] Andrew A
Patch from current to new Semaphore class design

Attachment: Semaphore_Managed.patch (application/octet-stream, text), 4.86 KiB.

[3 Jan 2008 23:18] Andrew A
Result class from the patch being applied and suggested replacement

Attachment: Semaphore.cs (octet/stream, text), 4.12 KiB.

[3 Jan 2008 23:19] Andrew A
Test Case - Run under Mono

Attachment: SemaphorePoolTest.cs (octet/stream, text), 599 bytes.

[3 Jan 2008 23:33] Andrew A
Additional PoolingTest NUnit Test

Attachment: PoolingTests_Updated.patch (application/octet-stream, text), 2.96 KiB.

[7 May 2008 19:25] 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:

[7 May 2008 19:26] Reggie Burnett
Fixed in 1.0.11.  This fix will not migrate past the 1.x series.
[8 May 2008 3:05] Andrew A

I've moved on to .Net 2 connector now anyway, but thanks for getting this pushed in.
[8 Jul 2008 14:09] Tony Bedford
An entry has been added to the 1.0.11 Changelog:

Attempting to utilize MySQL Connector .Net version 1.0.10 throws a fatal exception under Mono when pooling is enabled.