On 2013-11-11 17:42:50 +0000, Shammah Chancellor said:

On 2013-11-10 08:21:09 +0000, Sönke Ludwig said:

On Sat, 9 Nov 2013 14:45:30 -0500, Shammah Chancellor wrote:

Sönke,

Alright. I've tried using shared classes, Isolated classes, and

immutable classes. None of them work for a variety of reasons:

shared classes <-- Don't work because of external dependencies.

Making every member variable shared, breaks too much stuff.

Isolated classes <-- I need to be able to send the same reference to

multiple threads, so .move() is out of the question.

Immutable classes <-- Can't even get them to instantiate since the

constructors have to be strongly pure. Also, I can't deserialize into

an immutable class!

How am I supposed to send complex class messages?

R/

Shammah

You should try the lock() function in vibe.core.concurrency! It
uses a scheme if shared usage that Walter Bright once proposed in a
discussion and it makes shared with classes actually bearable.

Basically you just define a normal class without any shared
annotations, but create the instance using auto c = cast(shared)new <br>C. You will then not be able to use any methods of that class, but
calling c.lock() will give you back scoped access while the
instance's monitor is locked. Beware though that only access to pure
methods is allowed to guarantee safety (no unshared references must
escape), but this is currently not enforced due to compiler issues I
had some time ago (not sure how DMD 2.064 behaves now).

I tried using immutable messages again after some more reworking, and I
find that either std.concurrency or Vibe-D is trying to create the
parameters to the receiver() functions based on their type.

Code:

send( new immutable Foo() );
receive( (immutable Foo x) { ... } );

^-- can't work right now because internally it creates a list of
parameters as an IsolatedTypeTuple!(immutable Foo)

This fails inside of std.variant because IsolatedTypeTuple!(immutable
Foo) cannot be assigned to. It needs to wrap immutable reference
types with Rebindable!() somehow.

I don't want to use lock() since i'm only reading properties from the
class everywhere. That would cause the threads to block each other
while reading. I have fallen back to just casting to remove shared.
Seems like not a good solution though.

Here is a testcase:

import std.stdio;
import vibe.d;

class Foo
{
string msg;
this(immutable string msg) pure immutable
{

this.msg = msg;

}
}

static this()
{
auto foo = new immutable Foo(cast(immutable)"msg");
auto x = runTask( ()
{

receive((immutable Foo x)
    {
      writeln( x.msg);
    });

});

x.send(foo);
x.join();
}