<div class="gmail_quote">On Tue, Jan 12, 2010 at 5:16 PM, Andrei Alexandrescu <span dir="ltr"><<a href="mailto:andrei@erdani.com">andrei@erdani.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div class="im">Sean Kelly wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
On Jan 12, 2010, at 12:45 AM, Andrei Alexandrescu wrote:<br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
To be found at the usual location:<br>
<br>
<a href="http://erdani.com/d/fragment.preview.pdf" target="_blank">http://erdani.com/d/fragment.preview.pdf</a><br>
<br>
I didn't add a lot of text this time around but I do have a full example of communicating threads. Skip to the last section for explanation. I paste the code below. I think it looks pretty darn cool. Sean, please let me know if it floats your boat.<br>
<br>
import std.concurrency, std.stdio;<br>
<br>
void main() {<br>
auto low = 0, high = 1000;<br>
auto tid = spawn(&fun);<br>
foreach (i; low .. high) {<br>
writeln("Main thread: ", message, i);<br>
tid.send(thisTid, i);<br>
</blockquote>
<br>
I haven't been able to come up with any difference in implementation for using an interface vs. a free function that accepts an opaque type for sending messages, so the choice seems largely a matter of how you want the call to look. I'll admit that I like "send(tid, thisTid, i)" since it matches "receive(...)" but this is a small thing really.<br>
</blockquote>
<br></div>
You're echoing my thoughts as I was writing this. I'm undecided wrt tid.send(...) vs. send(tid, ...). I agree it is more symmetric with receive. Probably I'll use the free form. Other opinions?</blockquote><div>
<br>I like the free form better. Once you start using foo.method(...) you are implying that foo is the one stop shop for message passing behavior (or at least an important part of a balanced breakfast). If I see Logging::setLogLevel(...) in a program, I assume that all the invariants and what not (related to system logging anyway) are encapsulated in Logging's interface. If the other pieces are free functions then that isn't the case here.<br>
</div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div class="im">
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
enforce(receiveOnly!Tid() == tid);<br>
</blockquote>
<br>
This could be a wrapper for the usual recvmsg call, so no big deal.<br>
</blockquote>
<br></div>
Right. Note that receiveOnly is very strict: if you send anything else than what's expected, it raises an exception. This makes mailbox crowding impossible.<div class="im"><br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
What I'd like to do now that I haven't been able to because of a compiler bug is allow a timeout and catchall receiver to be supplied to the full recvmsg call:<br>
<br>
recvmsg( after(5, { writefln( "no message received!" ); },<br>
any( (Variant v) { writefln( "got something: %s", v ); } ) );<br>
</blockquote>
<br></div>
This is cute, perhaps a bit too cute. My objections are many but minor:<br>
<br>
* "recvmsg" is an awful name that evokes to me the name of a Cobol routine. It's very difficult to use in a conversation, and my accent doesn't help either :o). I think "receive" is a definite improvement.<br>
<br>
* Instead of after(...) as a clause, I'd rather have a receiveTimed (or recvmsgtmd if you wish) that takes a timeout value and returns true or false. I mean I'm not sure what moving the timeout code inside the call to recvms... I mean receive would gain us.<br>
<br>
* The "any" wrapper is, I think, unnecessary. Dispatching on Variant will always catch everything because everything is packed in a Variant to start with.<br>
<br>
So I'd rewrite your example as:<br>
<br>
if (!receiveTimed(5000,<div class="im"><br>
(Variant v) { writefln( "got something: %s", v ); }))<br></div>
{<br>
writefln( "no message received!" );<div class="im"><br>
}<br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
I guess the "any" wrapper could be dropped for the catchall routine and some special casing could be done inside recvmsg:<br>
<br>
recvmsg( (Variant v) {...} );<br>
</blockquote>
<br></div>
Ah, there we go.<div class="im"><br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
though I do kind of like that "any" (or whatever it would be called) is obvious at a glance and greppable.<br>
</blockquote>
<br></div>
Well I think understanding that messages are packed as one Variant must be very basic knowledge. You accept Variant => you accept anything.<div class="im"><br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
}<br>
// Signal the other thread<br>
tid.send(Tid(), 0);<br>
</blockquote>
<br>
I've considered having the sender's Tid automatically embedded in every message. Seems like it's pretty much always wanted, though this would mean not being able to use just any old delegate for receiving messages. ie. if you have a function already that accepts a Foo then would you want to use that directly or would it be a bother to wrap it in something to throw away the Tid?<br>
</blockquote>
<br></div>
Per Steve's point I think this has been settled.<div class="im"><br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Finally, I'd like for recvmsg to accept either a function returning void for "accept any of this type" as well as functions returning a bool for "if returns true, the passed value was a match, if false then not" to allow dynamic pattern matching. Seems like this should be easily possible with a static if inside the recvmsg loop, but I haven't actually tried it yet.<br>
</blockquote>
<br></div>
Sounds great! I'll add that explanation later on.<div class="im"><br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
}<br>
<br>
void fun() {<br>
for (;;) {<br>
auto msg = receiveOnly!(Tid, int)();<br>
if (!msg[0]) return;<br>
</blockquote>
<br>
Oh, so this format returns a Tuple for multiple arguments and the value for a single argument? The Tuple is gone by the time the user code is hit with recvmsg so it would have to rewrap it for receiveOnly, but if that's okay then this would work. I guess the other option would be a completely separate receiveOnly call instead of a wrapper, which could eliminate the extra work.<br>
</blockquote>
<br></div>
Yah, exactly. As long as it's just an implementation matter, it could use a bit of a roundabout mechanism. I think it saves the user of a fair amount of manual unpacking.<br>
<br>
I'm very glad to see this much shared vision!<br><font color="#888888">
<br>
<br>
Andrei</font><div><div></div><div class="h5"><br>
_______________________________________________<br>
dmd-concurrency mailing list<br>
<a href="mailto:dmd-concurrency@puremagic.com" target="_blank">dmd-concurrency@puremagic.com</a><br>
<a href="http://lists.puremagic.com/mailman/listinfo/dmd-concurrency" target="_blank">http://lists.puremagic.com/mailman/listinfo/dmd-concurrency</a><br>
</div></div></blockquote></div><br>