std.concurrency bug?

Charles Hixson via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue May 20 17:24:45 PDT 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:
> > 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);
	}
}




More information about the Digitalmars-d-learn mailing list