Open DemiMarie opened 6 years ago
I'm not familiar with the MySQL/MariaDB initialization problems you're referencing, but should this be reported to a lower-level package? Maybe https://github.com/paul-rouse/mysql ?
Sorry I'm a little late. I am not an expert on C++, so I am not 100% certain how this interacts with Haskell threads. Also, does it add any any significant overhead on each call checking whether the thread needs initialisation? The alternative in a Yesod site - using bound threads - also has some additional overhead, so it might not matter.
That said, when I get a bit of spare time, I intend to try out mysql-haskell
via persistent-mysql-haskell
. It completely avoids the problem by implementing the protocol in Haskell instead of using the standard client library, and think it is probably the way to go in the long run.
It is possible to solve the initialization problems when using the MariaDB/MySQL client drivers by using a single C++ source file and C++
thread_local
objects:C++:
Each Connector/C C function is wrapped in another C or C++ function that calls
MariaDB_Init()
first. The wrapper is called from Haskell.On Linux with
glibc
andlibstdc++
, this works because:pthread_key_create
are destroyed.We can also do this in pure C, by abusing
__cxa_thread_atexit_impl
, an undocumented function from the GNU C Library that is meant to be only called by the C++ runtime.On Windows, this doesn’t work reliably, because the destructors are called from
DllMain
which could fire after the MariaDB client library has already been unloaded. However, Windows doesn’t have high performance anyway, so this shouldn’t affect production uses.