On Monday, 14 August 2017 at 21:27:48 UTC, Jonathan M Davis wrote:
On Monday, August 14, 2017 15:22:23 Steven Schveighoffer via Digitalmars-d- learn wrote:
On 8/13/17 11:40 PM, Jonathan M Davis via Digitalmars-d-learn wrote: > On Saturday, August 12, 2017 18:57:44 Arek via > Digitalmars-d-learn
wrote:
>> 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?
>
> Unfortunately, send and receive do not currently work with > shared because of issues with Variant, which they use > internally.

This can't be a correct statement. This is the whole point of shared.

What's incorrect about it? It's a longstanding issue that because Variant can't contain shared data, send and receive do not work with shared. You can send and receive mutable data with no indirections, and AFAIK, you can send immutable data (though the OP is apparently having problems with that, so I guess that that doesn't work completely, though I definitely recall doing so previously), but you get compilation errors if you try to send shared data. For instance, this code

import std.concurrency;

void main()
{
    static void func(Tid parent)
    {
        auto received = receiveOnly!(shared int[string]);
    }

    shared int[string] aa;

    auto tid = spawn(&func, thisTid);
    send(tid, aa);
}


I've found some simple workaround for this problem:

import std.stdio;
import std.concurrency;

struct Envelope(T) if (is(T == class)) // for simplicity of this example, only classes
{
        shared(T)[] obj;

        this(shared T o)
        {
                this.obj = [o];
        }

        T get() @property nothrow @nogc
        {
                return cast() obj[0];
        }
}

class A
{

}

void consumer()
{
        auto r = receiveOnly!(Envelope!(A))();
        writeln("Got: ", typeof(r).stringof);
}

void main()
{
        auto cons = spawn(&consumer);
        auto o = Envelope!A(new A());
        send(cons, o);
}

Shared object can be encapsulated in the array. In case of other (non-class) types the pointer can be used, and get() should return ref to the pointed object (after stripping off the shared qualifier).

send() could encapsulate itself shared objectes.

Arek

Reply via email to