Does anyone understand how to use "shared" types with concurrency send/receive functions?

Arek via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Aug 12 11:57:44 PDT 2017


I have the folowing problem:
I like to envelope the class object in struct to control the 
destruction moment and then send this object to another 
thread/fiber (or task, cause I use vibe-d).

I can't find any method to make it working. Any ideas?

dmd (version 075) gives so stupid results, I belive it's broken 
(I've created the issue 
https://issues.dlang.org/show_bug.cgi?id=17749 )

ldc2 returns some errors:

.../import/std/variant.d(610,27): Error: function 
core.stdc.string.memcpy (void* s1, const(void*) s2, ulong n) is 
not callable using argument types (ubyte[32]*, 
shared(Env!(shared(A)))*, ulong)
.../import/std/conv.d(4186,9): Error: static assert  "Cannot 
emplace a Env!(shared(A)) because Env!(shared(A)).this(this) is 
annotated with @disable."
.../import/std/conv.d(4198,24):        instantiated from here: 
emplaceRef!(Env!(shared(A)), Env!(shared(A)), Env!(shared(A)))
.../import/std/variant.d(301,35):        instantiated from here: 
emplaceRef!(Env!(shared(A)), Env!(shared(A)))
.../import/std/variant.d(630,21):        instantiated from here: 
handler!(shared(Env!(shared(A))))
.../import/std/variant.d(544,17):        ... (5 instantiations, 
-v to show) ...
../../../.dub/packages/vibe-core-1.1.1/vibe-core/source/vibe/core/concurrency.d(1223,64):        instantiated from here: send!(shared(Env!(shared(A))))
app.d(74,7):        instantiated from here: 
send!(shared(Env!(shared(A))))



The code may be complied like this: dub --single --compiler=ldc2 
./app.d   (assuming it's saved in app.d file).


/+
dub.sdl:
name "simple"
dependency "vibe-core" version="~>1.1.0"
+/
import std.stdio;
import std.format;

import vibe.core.core;
import vibe.core.task;
import vibe.core.concurrency;

// simple class with destructor
shared class A
{
	int i;
	this(int i)
	{
		this.i = i;
	}

	~this()
	{
		writeln("destruct ", i);
	}

}

shared struct Env(T) if (is(T == class) && is(T == shared))
{
	T obj;

	this(T o)
	{
		obj = obj;
	}

	this(this)
	{
		// some magic here
	}

	auto opAssign(shared(Env!T) other)
	{
		obj = other.obj;
		return this;
	}

	auto opAssign(ref shared(Env!T) other)
	{
		obj = other.obj;
		return this;
	}

	~this()
	{
		if (obj !is null)
			destroy(obj);
		obj = null;
	}
}

void main()
{
	auto consumer = runTask({
		auto got = receiveOnly!(shared Env!(shared A))();
		writeln(typeof(got).stringof);
	});

	auto producer = runTask({
		auto a = new shared A(1);
		shared b = shared Env!(shared A)(a);
		writeln(typeof(b).stringof);
		send(consumer, b);
	});
	runApplication();
}



More information about the Digitalmars-d-learn mailing list