digitalmars.D.learn - std.concurrency bug?
- Charles Hixson via Digitalmars-d-learn (2/2) May 20 2014 Is it a bug that an immutable struct cannot be sent to a thread? (It co...
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (4/6) May 20 2014 Does the struct have any mutable indirection? Then it is illegal.
- Charles Hixson via Digitalmars-d-learn (29/37) May 20 2014 Nope. Here it is (with the immutable tags removed):
- Charles Hixson via Digitalmars-d-learn (96/104) May 20 2014 Nearly a minimal example. If "void sendMsg (Msg m){...}" is removed th...
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (19/24) May 21 2014 Further reduced:
- Charles Hixson via Digitalmars-d-learn (7/41) May 21 2014 Thanks. Fortunately, I don't really need for messages to be immutable, ...
- Sean Kelly (8/11) May 22 2014 std.concurrency actually uses Variant as the transport mechanism
Is it a bug that an immutable struct cannot be sent to a thread? (It compiles without problem if I make all elements mutable.)
May 20 2014
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
May 20 2014
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:Nope. Here it is (with the immutable tags removed): /** This is the only message that one cell sends to another. */ struct Msg uint64_t from; uint64_t to; /** 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() */ long tick; /** 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; } }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
May 20 2014
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:Nearly a minimal example. If "void sendMsg (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; enum numCThreads = 4; class UnexpectedMessage : Exception { this (string s) { super (s); } } enum Act {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 immutable uint64_t from; immutable uint64_t to; /** 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 long tick; /** 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; } } void cellThread(size_t ndx, shared(Tid)[] cThreads) Msg msgs[uint64_t][]; bool done = 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) { case Act.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 void sendMsg (Msg m) { assert (m.to > 0); assert (m.to < lastId); int ndx = m.to % numCThreads; Tid ct = cast(Tid)cThreads[ndx]; ct.send(m); } } // void cellThread() void main() { auto cellTids = new shared(Tid)[numCThreads]; foreach (id; 0 .. numCThreads) { auto cThread = spawn(&cellThread, id, cellTids); cellTids[id] = cast(shared(Tid))cThread; } foreach (cThread; cellTids) { Tid ct = cast(Tid)cThread; ct.send(Act.done); } }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
May 20 2014
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: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 AliOn 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.)
May 21 2014
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 AliThanks. 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.
May 21 2014
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=5538std.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.
May 22 2014