On Monday, 25 September 2017 at 01:46:15 UTC, Haridas wrote:
[...]
It all works well so far. But as soon as I create an instance
of Bar inside a Dlang class (say Foo) or as part of a Dlang
dynamic array, hell follows. At some point, Dlang's GC kicks in
and Bar's destructor gets called from within Dlang's GC. Now
since Dlang executes GC on a different thread, the destructor
gets confused and segfaults.
I actually wrote a C# style Dispatcher for exactly this reason. I
have D classes that own non thread-safe resources. So in the
destructor of the D class, I add a call that queues the
destruction to the main thread's dispatcher.
In your case, the postblit of Bar is still going to run and add a
ref to it's count when you place it in Foo, right? That means
that if you don't destroy it, it will leak memory or resources.
Unfortunately, my dispatcher is not production-ready yet, but you
can get around this with a simpler approach. Just keep a shared
container of your ref counted object type somewhere. When a
destructor of a GC class runs, move the ref counted object into
the trash container. Then, next time you want to create an
instance of the ref counted object, you can empty the trash
container at the same time. You should protect the container with
a Mutex of some kind. Also, be sure that the container doesn't
allocate using the GC since it will be called from class
destructors. IIRC std.container.Array uses malloc, not GC, so you
may be able to use that.