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();
}

Reply via email to