Re: std.concurrency bug?
On Wednesday, 21 May 2014 at 20:19:32 UTC, Ali Çehreli wrote: I think this is a known issue with immutable and Variant, which std.concurrency uses for unknown messages. This looks related: https://issues.dlang.org/show_bug.cgi?id=5538 std.concurrency actually uses Variant as the transport mechanism for all messages, and this is most likely the cause of your problem. If this is just to make a class pass type checking for transport, casting to shared is probably a better bet. The real solution is to make std.concurrency effectively allow uniquely referenced classes to be transferred, but that's a bit farther out.
Re: std.concurrency bug?
On 05/20/2014 05:24 PM, Charles Hixson via Digitalmars-d-learn wrote: On Tuesday, May 20, 2014 11:42:48 AM Ali Çehreli via Digitalmars-d-learn wrote: On 05/20/2014 11:38 AM, Charles Hixson via Digitalmars-d-learn wrote: Is it a bug that an immutable struct cannot be sent to a thread? (It compiles without problem if I make all elements mutable.) Further reduced: import std.concurrency; struct S { immutable int i; } void foo() {} void main() { auto f = spawn(foo); auto s = S(); f.send(s); } I think this is a known issue with immutable and Variant, which std.concurrency uses for unknown messages. This looks related: https://issues.dlang.org/show_bug.cgi?id=5538 Ali
Re: std.concurrency bug?
On Wednesday, May 21, 2014 01:19:32 PM Ali Çehreli via Digitalmars-d-learn wrote: On 05/20/2014 05:24 PM, Charles Hixson via Digitalmars-d-learn wrote: On Tuesday, May 20, 2014 11:42:48 AM Ali Çehreli via Digitalmars-d-learn wrote: On 05/20/2014 11:38 AM, Charles Hixson via Digitalmars-d-learn wrote: Is it a bug that an immutable struct cannot be sent to a thread? (It compiles without problem if I make all elements mutable.) Further reduced: import std.concurrency; struct S { immutable int i; } void foo() {} void main() { auto f = spawn(foo); auto s = S(); f.send(s); } I think this is a known issue with immutable and Variant, which std.concurrency uses for unknown messages. This looks related: https://issues.dlang.org/show_bug.cgi?id=5538 Ali Thanks. Fortunately, I don't really need for messages to be immutable, I just thought it would be safer (as in avoiding the possibility of making a mistake). They're stucts, and I never pass a pointer, just the struct. Being immutable would allow me to guarantee that certain logic errors couldn't be committed is all.
Re: std.concurrency bug?
On 05/20/2014 11:38 AM, Charles Hixson via Digitalmars-d-learn wrote: Is it a bug that an immutable struct cannot be sent to a thread? (It compiles without problem if I make all elements mutable.) Does the struct have any mutable indirection? Then it is illegal. Otherwise, can you demonstrate with minimal code please? Ali
Re: std.concurrency bug?
On Tuesday, May 20, 2014 11:42:48 AM Ali Çehreli via Digitalmars-d-learn wrote: On 05/20/2014 11:38 AM, Charles Hixson via Digitalmars-d-learn wrote: Is it a bug that an immutable struct cannot be sent to a thread? (It compiles without problem if I make all elements mutable.) Does the struct have any mutable indirection? Then it is illegal. Otherwise, can you demonstrate with minimal code please? Ali Nope. Here it is (with the immutable tags removed): /** This is the only message that one cell sends to another.*/ struct Msg { /** The cell id# of the sender of the message. */ uint64_tfrom; /** The cell id# of the recipient of the message. */ uint64_tto; /** The kind of action the message is impelling.*/ Act act; /** The tick on which the message was accepted for transmission. * This is set by std.datetime.Clock.currStdTime() */ longtick; /** Distance between cells. Not currently well defined except in * the case of two words, in which case it is the number of words of * separation, where adjacent is 1. */ float dist; /** Not currently well defined. */ int value; this(uint64_t from, uint64_t to, Act act, float dist, int value) { this.from = from; this.to = to; this.act= act; this.tick = Clock.currStdTime; this.dist = dist; this.value = value; } }
Re: std.concurrency bug?
On Tuesday, May 20, 2014 11:42:48 AM Ali Çehreli via Digitalmars-d-learn wrote: On 05/20/2014 11:38 AM, Charles Hixson via Digitalmars-d-learn wrote: Is it a bug that an immutable struct cannot be sent to a thread? (It compiles without problem if I make all elements mutable.) Does the struct have any mutable indirection? Then it is illegal. Otherwise, can you demonstrate with minimal code please? Ali Nearly a minimal example. If voidsendMsg (Msg m){...} is removed there's not compilation error. import std.array; import std.concurrency; import std.datetime; import std.format; import std.stdio; import std.stdint; import std.string; import std.variant; enumnumCThreads = 4; class UnexpectedMessage : Exception { this (string s) { super (s); } } enumAct {create, activate, deactivate, wait, read, reset, save, done} string toString(E)(E value) if (is(E == enum)) { foreach (s; __traits(allMembers, E)) { if (value == mixin(E. ~ s) ) return s; } return null; } // string toString (... for enum /** This is the only message that one cell sends to another.*/ struct Msg { /** The cell id# of the sender of the message. */ immutable uint64_tfrom; /** The cell id# of the recipient of the message. */ immutable uint64_tto; /** The kind of action the message is impelling.*/ immutable Act act; /** The tick on which the message was accepted for transmission. * This is set by std.datetime.Clock.currStdTime() */ immutable longtick; /** Distance between cells. Not currently well defined except in * the case of two words, in which case it is the number of words of * separation, where adjacent is 1. */ immutable float dist; /** Not currently well defined. */ immutable int value; this(uint64_t from, uint64_t to, Act act, float dist, int value) { this.from = from; this.to = to; this.act= act; this.tick = Clock.currStdTime; this.dist = dist; this.value = value; } } voidcellThread(size_t ndx, shared(Tid)[] cThreads) { /** Unprocessed message queue, indexed by cell id#. */ Msg msgs[uint64_t][]; booldone= false; //TODO load the cells into the thread /** Receive all messages in the mailbox. Wait 2 ns for response. */ while (!done receiveTimeout (0.seconds, (Msg m) { if (m.to in msgs) { msgs[m.to] ~= m; } else { msgs[m.to] = [m]; } }, (Act act) { switch (act) { caseAct.done: // end cell processing done= true; break; default: auto s = format ( Error in thread %s: received message Act.%s, ndx, act); writefln (s); throw new UnexpectedMessage(s); } // switch (act) } //(Act act) ) ) { } // while (!done receiveTimeout voidsendMsg (Msg m) { assert (m.to 0); assert (m.to lastId); int ndx = m.to % numCThreads; Tid ct = cast(Tid)cThreads[ndx]; ct.send(m); } } // voidcellThread() voidmain() { autocellTids= new shared(Tid)[numCThreads]; foreach (id; 0 .. numCThreads) { autocThread = spawn(cellThread, id, cellTids); cellTids[id]= cast(shared(Tid))cThread; } foreach (cThread; cellTids) { Tid ct = cast(Tid)cThread; ct.send(Act.done); } }