July 31, 2015
Hi

Coming back after a (too long) break from D programming.

Using DMD 2.067.1:

# cat receive_subclass.d

import std.stdio; import std.concurrency;

class A {}
class B : A {}

void worker () {
  while (true) {
    receive(
      (shared B b) { writefln( "Got B: %s", cast(B)b ); },
      (shared A a) { writefln( "Got A: %s", cast(A)a ); }
    );
  }
}

void main () {
  shared A arg = new B;
  Tid tid = spawn(&worker);
  send( tid, arg);
  send( tid, cast(shared B)arg);
  receive( (bool) {} ); // wait
}

# dmd -run receive_subclass.d
Got A: receive_subclass.B     // XXX: we got B, but it was matched as A
Got B: receive_subclass.B

So patten matching only works on type of containing variable, not the type of the object itself. Is it possible to work around this? I need to receive objects from rather large subclass hierarchy and it would be much more convenient for me to recognize particular subclass using receive than some type of multiple "cast & check" clauses.

On a related matter - how does GC behave on such class objects (created in one thread, casted to shared and handled by another thread)? Won't the object get possibly GC'ed when it runs out of scope in origin thread while handler thread still uses it?

-- 
Marek Janukowicz
July 31, 2015
On Friday, 31 July 2015 at 07:35:47 UTC, Marek Janukowicz wrote:
> So patten matching only works on type of containing variable, not the type of the object itself. Is it possible to work around this?

No, it would be very surprising if receive performed a dynamic downcast, and it's also somewhat expensive.
If you want that, do the downcast in your handler yourself.

> Won't the object get possibly GC'ed when it runs out of scope in origin thread while handler thread still uses it?

No, the GC pauses and scans all threads for roots.