www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - std.concurrency : sending immutable classes

reply "Dicebot" <public dicebot.lv> writes:
This prints nothing:

```
import std.concurrency;
import std.stdio;

class A
{
     string toString() immutable
     {
         return "aaa";
     }
}

void thread()
{
     for (;;)
     {
         receive(
             (immutable A x) {
                 writeln(x);
             },
             (Variant x) {
                 writeln(x.type);
                 writeln(x);
             }
         );
     }
}

void main()
{
     auto tid1 = spawn(&thread);
     auto val = new immutable A();
//    tid1.send(42);
     tid1.send(val);
     for (;;) {}
}

}
```

Any ideas? :)
Nov 11 2013
next sibling parent reply "Gary Willoughby" <dev nomad.so> writes:
On Monday, 11 November 2013 at 18:54:04 UTC, Dicebot wrote:
 Any ideas? :)
This is one way: import std.concurrency; import std.stdio; shared class A { public string toString() { return "aaa"; } } void thread() { for (;;) { receive( (shared A x) { writeln(x.toString()); }, (Variant x) { writeln(x.type); writeln(x); } ); } } void main() { auto tid1 = spawn(&thread); auto val = new shared(A)(); // tid1.send(42); tid1.send(val); for (;;) {} } I must admit the concurrency confuses me and i need to play with it more. :)
Nov 11 2013
parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 11 November 2013 at 19:18:20 UTC, Gary Willoughby 
wrote:
 On Monday, 11 November 2013 at 18:54:04 UTC, Dicebot wrote:
 Any ideas? :)
This is one way: ...
No, I am perfectly aware of shared part, point is exactly about sending immutable ones (which are implicitly shared by design). What bothers me most is that I can't imagine what code flow it takes to print no output and no errors as (Variant v) is supposed to catch everything.
Nov 11 2013
next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, November 11, 2013 21:10:20 Dicebot wrote:
 On Monday, 11 November 2013 at 19:18:20 UTC, Gary Willoughby
 
 wrote:
 On Monday, 11 November 2013 at 18:54:04 UTC, Dicebot wrote:
 Any ideas? :)
This is one way: ...
No, I am perfectly aware of shared part, point is exactly about sending immutable ones (which are implicitly shared by design). What bothers me most is that I can't imagine what code flow it takes to print no output and no errors as (Variant v) is supposed to catch everything.
Maybe it missed the Variant due to a mismatch in constness? In my experience, receive is _very_ picky about the type. It pretty much has to match exactly, and while Variant may work to get the stuff that misses in most cases, it wouldn't surprise me at all if a difference in constness threw it off. But that's just a guess. I'd have to go digging through the code and experiment to figure out why what you're doing isn't working. - Jonathan M Davis
Nov 11 2013
next sibling parent Dejan Lekic <dejan.lekic gmail.com> writes:
Could it be something changed in DMD recently, as in my case (DMD64 D 
Compiler v2.063.2, on Fedora GNU/Linux) it obviously picks Variant. Why 
it does not pick the immutable instance of A is beyond me. If we reverse 
the order of arguments in the receive(), we will get the "function with 
arguments (VariantN!(32LU)) occludes successive function" error...
Nov 11 2013
prev sibling parent "Dicebot" <public dicebot.lv> writes:
Updated case after some experiments:
```
import std.concurrency;
import std.stdio;

class A
{
     override string toString() const // this was an issue, it 
must be exact override
     {
         return "aaa";
     }
}

void thread()
{
     for (;;)
     {
         receive(
/*            (immutable(A) x) {
                 writeln("what");
             }, */
             (Variant x) {
                 writeln(x.type);
                 writeln(x);
             }
        );
     }
}

void main()
{
     auto tid1 = spawn(&thread);
     auto val = new immutable A();
     tid1.send(val);
     for (;;) {}
}
```

This prints expected:
```
immutable(test.A)
aaa
```

However, uncommenting `immutable(A)` receiver makes it silent 
again.
Nov 11 2013
prev sibling parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 11/11/13 21:10, Dicebot wrote:
 No, I am perfectly aware of shared part, point is exactly about sending
 immutable ones (which are implicitly shared by design). What bothers me most is
 that I can't imagine what code flow it takes to print no output and no errors
as
 (Variant v) is supposed to catch everything.
Based on my experience with std.concurrency, most likely you've either got a type mismatch (so the thread is not recognizing the message, even though you think it should) or you've got an error being thrown (the message for which won't be printed if it's thrown in the thread).
Nov 11 2013
parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 11 November 2013 at 23:21:14 UTC, Joseph Rushton 
Wakeling wrote:
 (the message for which won't be printed if it's thrown in the 
 thread).
Whoa, didn't know that, I thought it will terminate the thread and cause related exception in owner thread. I have just checked it an yeah, assertion error is thrown: core.exception.AssertError /usr/include/dlang/dmd/std/variant.d(287): immutable(A) ---------------- /tmp/.rdmd-1000/rdmd-test.d-076D4362D54E9EAA8F49CE8F8A45511D/test _d_assert_msg+0x45) [0x462d9d] /tmp/.rdmd-1000/rdmd-test.d-076D4362D54E9EAA8F49CE8F8A45511D/test(bool std.variant.VariantN!(32uL).VariantN.handler!(immutable(test.A)).handler(std.variant.VariantN!( 2uL).VariantN.OpID, ubyte[32]*, void*).tryPutting(immutable(test.A)*, TypeInfo, void*)+0x8d) [0x461665] /tmp/.rdmd-1000/rdmd-test.d-076D4362D54E9EAA8F49CE8F8A45511D/test( trusted long std.variant.VariantN!(32uL).VariantN.handler!(immutable(test.A)).handler(std.variant.VariantN!( 2uL).VariantN.OpID, ubyte[32]*, void*)+0xc3) [0x461393] /tmp/.rdmd-1000/rdmd-test.d-076D4362D54E9EAA8F49CE8F8A45511D/test( property trusted immutable(test.A) std.variant.VariantN!(32uL).VariantN.get!(immutable(test.A)).get()+0x68) [0x45ee28] /tmp/.rdmd-1000/rdmd-test.d-076D4362D54E9EAA8F49CE8F8A45511D/test(void std.concurrency.Message.map!(void function(immutable(test.A))*).map(void function(immutable(test.A))*)+0x5a) [0x45edb2] /tmp/.rdmd-1000/rdmd-test.d-076D4362D54E9EAA8F49CE8F8A45511D/test(bool std.concurrency.MessageBox.get!(void function(immutable(test.A))*, void function(std.variant.VariantN!(32uL).VariantN)*).get(scope void function(immutable(test.A))*, scope void function(std.variant.VariantN!(32uL).VariantN)*).bool onStandardMsg(ref std.concurrency.Message)+0x31) [0x45e7a9] /tmp/.rdmd-1000/rdmd-test.d-076D4362D54E9EAA8F49CE8F8A45511D/test(bool std.concurrency.MessageBox.get!(void function(immutable(test.A))*, void function(std.variant.VariantN!(32uL).VariantN)*).get(scope void function(immutable(test.A))*, scope void function(std.variant.VariantN!(32uL).VariantN)*).bool scan(ref std.concurrency.List!(std.concurrency.Message).List)+0xe6) [0x45eb06] /tmp/.rdmd-1000/rdmd-test.d-076D4362D54E9EAA8F49CE8F8A45511D/test(bool std.concurrency.MessageBox.get!(void function(immutable(test.A))*, void function(std.variant.VariantN!(32uL).VariantN)*).get(scope void function(immutable(test.A))*, scope void function(std.variant.VariantN!(32uL).VariantN)*)+0x17f) [0x45e6e7] /tmp/.rdmd-1000/rdmd-test.d-076D4362D54E9EAA8F49CE8F8A45511D/test(void std.concurrency.receive!(void function(immutable(test.A))*, void function(std.variant.VariantN!(32uL).VariantN)*).receive(void function(immutable(test.A))*, void function(std.variant.VariantN!(32uL).VariantN)*)+0x83) [0x45e553] /tmp/.rdmd-1000/rdmd-test.d-076D4362D54E9EAA8F49CE8F8A45511D/test(void test.thread()+0x2a) [0x45b782] /tmp/.rdmd-1000/rdmd-test.d-076D4362D54E9EAA8F49CE8F8A45511D/test(_D3std11concurrency16__T6_spawnTPFZvZ6_spawnFbPFZvZS3std11concurrenc 3Tid4execMFZv+0x42) [0x46116a] /tmp/.rdmd-1000/rdmd-test.d-076D4362D54E9EAA8F49CE8F8A45511D/test(void core.thread.Thread.run()+0x2a) [0x47c9da] /tmp/.rdmd-1000/rdmd-test.d-076D4362D54E9EAA8F49CE8F8A45511D/test(thre d_entryPoint+0x165) [0x47c761]
Nov 11 2013
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
Minimized repro:

import std.variant;

class A {}

void main()
{
     Variant v = new immutable A();
     auto x = v.get!(immutable A)();  // triggers assert
}

One simple question - did this ever work? :) Because passing 
immutable aggregate messages is sometimes sold as one of "proper" 
usage scenario of std.concurrency and if it was never actually 
implemented, that is damn sad. I have started to investigate this 
scenario because of question on topic in #d   freenode.
Nov 11 2013
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, November 12, 2013 00:37:30 Dicebot wrote:
 Minimized repro:
 
 import std.variant;
 
 class A {}
 
 void main()
 {
      Variant v = new immutable A();
      auto x = v.get!(immutable A)();  // triggers assert
 }
 
 One simple question - did this ever work? :) Because passing
 immutable aggregate messages is sometimes sold as one of "proper"
 usage scenario of std.concurrency and if it was never actually
 implemented, that is damn sad. I have started to investigate this
 scenario because of question on topic in #d   freenode.
I believe that in the past, Variant hasn't worked with immutable, so if it doesn't work with it now, then presumably, that was never fixed. - Jonathan M Davis
Nov 11 2013
prev sibling parent Dejan Lekic <dejan.lekic gmail.com> writes:
On Tue, 12 Nov 2013 00:37:30 +0100, Dicebot wrote:

 Minimized repro:
 
 import std.variant;
 
 class A {}
 
 void main()
 {
      Variant v = new immutable A();
      auto x = v.get!(immutable A)();  // triggers assert
 }
 
 One simple question - did this ever work? :) Because passing immutable
 aggregate messages is sometimes sold as one of "proper"
 usage scenario of std.concurrency and if it was never actually
 implemented, that is damn sad. I have started to investigate this
 scenario because of question on topic in #d   freenode.
Looks like Variant works only with implicitly convertible types. In this case this fails: assert(isImplicitlyConvertible!(immutable(A), A));
Nov 11 2013
prev sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 12/11/13 00:31, Dicebot wrote:
 On Monday, 11 November 2013 at 23:21:14 UTC, Joseph Rushton Wakeling wrote:
 (the message for which won't be printed if it's thrown in the thread).
Whoa, didn't know that, I thought it will terminate the thread and cause related exception in owner thread. I have just checked it an yeah, assertion error is thrown:
Yea, it's unintuitive -- I got bitten by it earlier in the year: http://forum.dlang.org/thread/51D16259.1010009 webdrake.net
Nov 11 2013
prev sibling parent Dejan Lekic <dejan.lekic gmail.com> writes:
When I run this program, I get a runtime error which gives me a headache:
http://codepad.org/vKJl11cO
Nov 11 2013