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  "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
{       /**     The cell id# of the sender of the message.      */
        immutable       uint64_t        from;
        /**     The cell id# of the recipient of the message.   */
        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)
{       /**     Unprocessed message queue, indexed by cell id#. */
        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);
        }
}


Reply via email to