What would you do...

Timon Gehr timon.gehr at gmx.ch
Thu Dec 8 11:43:33 PST 2011


On 12/08/2011 05:23 PM, Manu wrote:
> On 8 December 2011 17:51, Manu <turkeyman at gmail.com
> <mailto:turkeyman at gmail.com>> wrote:
>
>     On 8 December 2011 16:27, Jens Mueller <jens.k.mueller at gmx.de
>     <mailto:jens.k.mueller at gmx.de>> wrote:
>
>         Manu wrote:
>          > On 8 December 2011 00:20, Manu <turkeyman at gmail.com
>         <mailto:turkeyman at gmail.com>> wrote:
>          >
>          > > Hey peoples,
>          > >
>          > > So this might be a bit off topic... but I'm trying to think
>         about the best
>          > > way to write a small program in the most D-ish way possible
>         (just to make
>          > > sure I'm giving myself the most realistic experience with
>         the language),
>          > > and I wanted to get some thoughts.
>          > > I don't know which way to go on this. I know what I'd do in
>         various other
>          > > languages, but I'm curious to hear the communities opinion.
>         I think part of
>          > > the problem is that D's networking libraries are pretty
>         incomplete... but
>          > > here it is anyway.
>          > >
>          > > I basically just want to write a trivial echo server which
>         may have
>          > > hundreds of thousands of connections split into small
>         groups, and whenever
>          > > data is received from a member in any group, it is
>         basically echoed to the
>          > > others in that group.
>          > > Sounds super simple...
>          > >
>          > > My instinct is to have a listener on the main thread, and
>         spawn a thread
>          > > per group, each blocking on a select().. I think the
>         questions is around
>          > > thread safety and group management (managing the connection
>         list for each
>          > > group), and how to interrupt a blocking select() when a new
>         connection has
>          > > entered the group...
>          > > "The D way" to solve these questions is a mystery to me. I
>         just feel like
>          > > I'm writing C code, manually managing thread safety,
>         timeout logic. I feel
>          > > like D offers some fundamental features that should make
>         solving this
>          > > problem a whole lot simpler that I must be completely
>         missing...
>          > >
>          > > So, in a few sentences... simple problem, what would you do?
>          > >
>          >
>          > Nobody at all? :(
>          >
>          > Quite seriously. I'm trying to work out how D's
>         threading/thread safety
>          > architecture can help me here.. Also since there's no
>         collections, I'm
>          > using the associative arrays. How do I manage thread safety
>         when accessing
>          > those? Is there a generic lock mechanism that I've missed
>         along the way
>          > without manually creating semaphores? Networking does seem to
>         be pretty
>          > bare, I'm basically writing C sockets code.
>          > One of the results of my experiment here is to identify some
>         critical
>          > things that appear to be missing from the language. Places
>         libraries should
>          > really step in and make the task simple. This is a super
>         simple network
>          > app, but so far, it's just as complicated as if it were
>         written in C.
>
>         I'm probably wrong or not getting it.
>         But to me it seems you have two different things:
>         First threads and second connections. For the first I would give
>         std.concurrency a try (message passing between the threads). And
>         managing a set of connections within a thread is plain C. So using
>         select as you do is probably good. If you need to adjust the
>         select call
>         from time to time you should not let select block indefinitely.
>         Use a
>         timeout. Another option is pselect which has a signal mask. I
>         suppose
>         this can also be used to signal abort.
>
>         Jens
>
>
>     This is basically exactly what I have (although I'm using
>     core.thread, I'll swap it for std.concurrency, it does look nicer).
>     But it just feels... lame/./
>     I'm not sure why though, I can't quite put my finger on it. Maybe
>     something irks me about using select() this way, it feels, 1980s :P
>
>     The std.concurrency documentation is pretty bad.
>     So is std.concurrency.spawn() just effectively a helper for spawning
>     a thread that has mailbox support?
>     std.concurrency.receive() has no documentation ;) ..
>     Blocking/Non-blocking? Should I use the one with duration==0 to do a
>     poll? Perhaps there should be an explicit poll() method?
>     What is prioritySend()? (also undocumented)
>
>
> Just digging through concurrence.d since the docs are pretty bare, and
> I've come across this pattern, which raises a pretty worrying alarm to
> me. I wonder if this is common in D libraries...
>
>
> void receive(T...)( T ops )
>
> {
>
> checkops( ops );
>
> mbox.get( ops );
>
> }
>
>
> bool receiveTimeout(T...)( Duration duration, T ops )
>
> {
>
> checkops( ops );
>
> return mbox.get( duration, ops );
>
> }
>
>
> Okay, so one calls mbox.get with a duration, makes sense... there must
> be an overload...
>
> finalboolget(T...)(Tvals)
>
> {
> static assert( T.length );
>
> static if( isImplicitlyConvertible!(T[0], Duration) )
>
> {
> alias TypeTuple!(T[1 .. $]) Ops;
>
> alias vals[1 .. $] ops;
>
> assert( vals[0] >= dur!"msecs"(0) );
>
> enum timedWait = true;
>
> Duration period = vals[0];
>
> }
> else
> {
> ... blah blah
>
>
> No overload, receives a tuple, and assumes that static-if the first
> tuple item is IMPLICITLY CONVERTIBLE to a Duration, I must be calling
> the 'overload'...
>
> I guess this means I can never pass a Duration in a message to the
> non-timeout receive()... or anything that is implicitly convertible to a
> Duration.

Sure, receive cannot be called with duration. You pass callbacks to it, 
not Durations. Callbacks are never implicitly convertible to Durations, 
so that is fine.

> This would seem to be a very obscure hidden bug to me. Is this a common
> pattern in D?

I don't see a 'pattern'.

> I certainly wouldn't want to be tracking down this bug on build
> night... Is there something I've missed here? Some sort of safeguard
> I've overlooked?

Have a look at the checkops template. It catches your case.
I just saw it contains another bug though:

static assert( is( t1 == function ) || is( t1 == delegate ) );

Obviously, the writer meant to check for function pointers and 
delegates. This is not what it does. Borken. I think the language should 
be fixed here.





More information about the Digitalmars-d mailing list