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