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

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Aug 14 14:27:48 PDT 2017


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

will fail to compile with

/usr/local/include/dmd/std/variant.d(625): Error: function 
core.stdc.string.memcpy (return scope void* s1, scope const(void*) s2, ulong 
n) is not callable using argument types (ubyte[32]*, shared(int[string])*, 
ulong)
/usr/local/include/dmd/std/variant.d(625): Error: function 
core.stdc.string.memcpy (return scope void* s1, scope const(void*) s2, ulong 
n) is not callable using argument types (ubyte[32]*, shared(int)*, ulong)
/usr/local/include/dmd/std/variant.d(424): Error: template instance 
std.variant.VariantN!32LU.VariantN.opAssign!(shared(int)) error 
instantiating
/usr/local/include/dmd/std/variant.d(645):        instantiated from here: 
handler!(shared(int[string]))
/usr/local/include/dmd/std/variant.d(559):        instantiated from here: 
opAssign!(shared(int[string]))
/usr/local/include/dmd/std/concurrency.d(101):        instantiated from 
here: __ctor!(shared(int[string]))
/usr/local/include/dmd/std/concurrency.d(606):        ... (2 instantiations, 
-v to show) ...
/usr/local/include/dmd/std/concurrency.d(576):        instantiated from 
here: _send!(shared(int[string]))
q.d(13):        instantiated from here: send!(shared(int[string]))

whereas if you use something like int, it has no problem. It won't even
compile if you give it a shared int, and that arguably should just be
converting to and from int, since shared int has no indirections.

There are at least two bugs reported on the issue:

https://issues.dlang.org/show_bug.cgi?id=13262
https://issues.dlang.org/show_bug.cgi?id=14893

I suspect that the solution involves making it so that std.concurrency uses
something other than Variant to store the data being sent, but regardless,
no one has fixed the issue yet. So, while send and receive work fine for
simple message, they're fairly crippled when it comes to complex data and
have been for their entire existence AFAIK.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list