On 8/14/17 5:27 PM, Jonathan M Davis via Digitalmars-d-learn 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.

The implementation details aren't important. From the documentation (and no, this documentation is not wrong):

From spawn:
args must not have unshared aliasing. In other words, all arguments to fn must either be shared or immutable or have no pointer indirection. This is necessary for enforcing isolation among threads.

From send:
As with std.concurrency.spawn, T must not have unshared aliasing.

So clearly passing shared pointers or things containing shared pointers should work fine.

As I was building code to test, I found that it does actually work for shared int pointers:

import std.concurrency;
import std.typecons;
import std.stdio;
import core.thread;

void threadfunc()
{
    bool done = false;
    while(!done)
    {  receive(
                  (shared(int)*foo) {*foo = 5; done = true;},
                  (Variant v) {}
                  );
    }
}

shared int f;

void main()
{
    auto tid = spawn(&threadfunc);
    tid.send(&f);
    Thread.sleep(1.seconds);
    writeln(f);
}


No error, completes as expected, and outputs 5.

So it looks like this is really a straight up bug and has nothing to do with the shared type qualifier. It is documented as working, and does work in some cases.

I think if the shared item is not a reference, it is doing something different, and this is incompatible with something in the implementation. Indeed, if you attempt to send unshared references, you get an assert. However, if you send a shared int (not a pointer), you get a bunch of compiler errors. Clearly the implementation expects it to work, as it doesn't fail the logical checks.

-Steve

Reply via email to