Calling D library from other languages on linux using foreign threads

tchaloupka chalucha at gmail.com
Sat Mar 23 17:33:31 UTC 2019


On Saturday, 23 March 2019 at 15:28:34 UTC, Ali Çehreli wrote:
> On 03/22/2019 12:34 PM, tchaloupka wrote:
> > I've searched a lot at it should be working at least on
> linux, but
> > apparently is not or I'm doing something totally wrong..
> >
> > Our use case is to call shared D library from C# (.Net Core)
> and from
> > different threads.
>
> We needed to do the same from Java. I opened this discussion:
>
>   https://forum.dlang.org/thread/p0dm8f$ij5$1@digitalmars.com
>
> and abandoned this pull request:
>
>   https://github.com/dlang/druntime/pull/1989
>
> We didn't need to pursue this further because the person who 
> was pushing for D was leaving the company, so he rewrote the 
> library in C++ before doing so.
>
> I don't think it's possible to call into D's GC from another 
> thread in a safe way. If I remember correctly, there is no 
> absolute way in POSIX (or just Linux?) of knowing that a 
> foreign thread has died. D's GC would be holding on to an 
> already dead thread.
>
> Ali

That's pretty unfortunate.
I know about your thread and PR, that's why I've tried to solve 
this by calling thread_attachThis()/thread_detachThis() in every 
worker function call.

But that doesn't work in compilers > dmd-2.078.1.

Actually after fiddling with this some more, I've discovered that 
when I call this method:

```D
void* entry_point2(void*)
{
	printf("+entry_point2\n");
	scope (exit) printf("-entry_point2\n");

	// This thread gets registered in druntime, does some work and 
gets
	// unregistered to be cleaned up manually
	if (!thread_isMainThread()) // thread_attachThis will hang 
otherwise
	{
		printf("+entry_point2 - thread_attachThis()\n");
		thread_attachThis();
		rt_moduleTlsCtor();
	}

	// simulate GC work
	auto x = new int[100];
	GC.collect();

	if (!thread_isMainThread())
	{
		printf("+entry_point2 - thread_detachThis()\n");
		rt_moduleTlsDtor();
		thread_detachThis();
	}
	return null;
}
```

from the main thread, it works too. I've observed, that:

* auto x = new int[100]; needs to be there as it doesn't work 
otherwise
* but it works only with some array lengths (I guess due to some 
GC decision when to kick in) - so is unreliable
* it still hangs sometimes on thread_detachThis()


I've no idea what should be done with C's main thread as it can't 
be attached because it'll hang.
In one of forum threads I've also read the idea to not using 
foreign threads with GC but somehow delegate their work to D's 
thread.
Can this work somehow? But `new Thread()` would still be needed 
to call from C side or static this() but from C's thread.



More information about the Digitalmars-d-learn mailing list