[dmd-concurrency] priority messages

Michel Fortin michel.fortin at michelf.com
Mon Jan 25 08:08:25 PST 2010


Le 2010-01-25 à 9:42, Andrei Alexandrescu a écrit :

> I found a weakness of the priority messaging system. Recall that my plan was to do the following: if a message inherits Exception and is not explicitly expected in receive(), it causes receive() to throw that very message. (There was discussion on whether the right base is Exception/Throwable/Error.)
> 
> That approach nicely uses an existing mechanism to send out-of-band values into the control flow. I really think that's a Good Thing, but I realized there's a problem. Actually two.
> 
> 1. What if I want to send an int with priority? Throwing an int is a rather absurd proposition, but sending an int to a thread is a very reasonable thing to ask for.
> 
> 2. Exceptions are class objects, so the whole issue of undue sharing and consequently marshaling/unmarshaling across threads comes up.
> 
> So I'd like to change the approach. Instead of doing a type-based priority system (i.e. certain types are priority messages), let's define a per-call based priority system (i.e. if you call prioritySend() instead of send() the message has priority).
> 
> In this proposed approach, if receive() does not explicitly handle the message sent with priority, it will be packaged as an exception PriorityMessageException!T, where T is the original type sent. The advantage is that the exception will be created and thrown in the receiving thread (no need to be careful about cross-thread aliasing of the exception object.

Personally I'd tend to just not define any priority and deal with things in a FIFO manner to keep things simple. If you want to add complexity (priority), it should be justified by use cases. So which use case do you have in mind for priority? 

About sending exceptions, I see two possibilities: either you manually send an exception, or a thread is terminated by an exception. In the first case, you'll need the exception to be either immutable, shared, or Unique!Exception. In the second case, which according to my Thread Termination protocol the exception gets sent to the owner thread, the terminating thread can safely cast the thread-local exception to Unique!Exception since all other thread-local references are lost when the thread terminates.

About throwing Exceptions in receive... I've been thinking lately and I wonder if this couldn't be generalized a bit more, using a libdispatch-inspired API. What if instead of receive() having a special case for exceptions it had a special case for shared delegates and functions? You could then do this:

	tid.send({ throw new Exception(); });

The interesting result is that any thread can instantly becomes a worker queue.


-- 
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/





More information about the dmd-concurrency mailing list