Bane wrote:
Following code will freeze app on std.gc.fullCollect(), when sqlite3_close() in
destructor is called. If destructor is called manualy, everything goes ok.
Is it a bug, and if is, with what? It behaves same on winxp64 and centos5.2
using dmd 1.30 and sqlite 3.6.5 or 3.6.19 statically import lib. Libraries are
tested so I do not suspect problem lies in them (they are compiled with dmc/gcc
using full threading support).
It's not your fault, it's a well known bug. The following is what happens:
- in thread 1, a C function (e.g. malloc()) enters an internal lock
- while thread 1 holds the lock, thread 2 triggers a D garbage
collection cycle
- thread 2 pauses all threads forcibly, including thread 1
- thread 2 collects some objects and calls finalizers on it
- your finalizer calls a C function, which tries to enter the same lock
that is held by thread 1
- but thread 1 has been paused
- the GC won't resume the other threads until your function returns, and
you have a deadlock
As a solution, switch to D2 or Tango. These resume all suspended threads
before running the finalizers.