On Friday, 8 December 2017 at 09:33:03 UTC, Ali Çehreli wrote:
One idea was to attach and detach in every api function something to the effect of

extern(C) my_api_func() {
    thread_attachThis();
    scope(exit) thread_detachThis();

    // Do work, potentially producing garbage...
}

Does that make sense? Wouldn't garbage produced by that thread leaked after detaching?

It makes sense.
AFAIK Detaching a thread deregisters its stack (local holding GC objects). And if the data was referred only by the thread stack and this range was removed, then why couldn't the data be reclaimed?

I don't know what this implies for TLS roots though.

2) Obviously, Runtime.initialize() must be called for Druntime to work at all. Question: Is the thread that calls Runtime.initialize() special compared to the other threads? Can this thread disappear and the Druntime still work?

Don't know for sure, but I believe it's not a special thread and can disappear.


3) An attached non-D thread can exit without any notice (gracefully or otherwise) while it's still attached to D's GC, causing segmentation faults or deadlock.

Isn't this an unrecoverable error?
- either you have failed deregistering the thread which got killed outside your dynlib
  - either you killed it while it was attached

So, what are the rules of using D as a library for a non-D framework? I have the following so far but I'm not sure on all points:

- SURE: One thread must make a call to Runtime.initialize()

- SURE: Every D api call must call thread_attachThis

I advise to make a RAII struct you will put in any accessible callback, which deals with this. Runtime finalization needs a special place though => harder.

The remaining problem is races, having interlocked singleton initialization without the runtime is a mystery to me.

- SURE: Attached threads must *not* terminate gracefully, due to error, or by cancellation. (As there is no way of guaranteeing this in POSIX, I think using D as a library in a framework is best-effort at best.)

Since you get those threads from the outside it's certainly impolite to terminate them.

- NOT SURE: thread_detachThis must *not* be called as the thread may have uncollected garbage.

IMHO thread_detachThis *must* be called at entry-point exit.
Detach these threads at scope(exit), and avoid sorrow and call stacks with pthread_kill inside.


Reply via email to