Possible to pass a member function to spawn?
timon.gehr at gmx.ch
Wed Feb 8 17:46:21 PST 2012
On 02/09/2012 12:50 AM, Artur Skawina wrote:
> On 02/08/12 22:47, Timon Gehr wrote:
>> On 02/08/2012 10:26 PM, Artur Skawina wrote:
>>> If we effectively passed ownership of our unique instance to another context, 'x' can no longer
>>> be "unique". If it were to mutate to the target type, then leaving it
>>> accessible from the current context should be reasonably safe.
>> The idea was that spawn could take unique class references and pass ownership to a different thread -- eliminating the need to cast to and from shared.
> I'll rephrase what i said in that d.learn post; *all* I'm suggesting is this:
> a) Any result of an expression that the compiler can determine is unique is
> internally flagged as such. This means eg array concatenation or new-expressions.
> Just a simple bitflag set, in addition to the the stored "real" type.
> b) Any access to the data clears this flag (with just a few exceptions, below).
> c) If the expression needs to be implicitly converted to another type *and*
> no implicit cast is possible *and* the "unique" flag is set - then additional
> safe conversions are tried, and if one succeeds, the "unique" flag gets cleared
> and the type gets modified to the that of the target.
> This allows for things which are 100% safe, but currently prohibited by the
> compiler and require explicit casts.
Your 'simple bit flag' already necessitates a flow analysis, and it does
not solve the problem Manu describes. Why not make it powerful enough to
> If I understood you right, you'd like (b) to be much less restrictive, which i
> think complicates things too much. Some (b)-restrictions for cases that always
> are cheap to discover /can/ be removed, but this needs to be determined on a case-
> -by-case basis.
Everything that can modularly be shown to work should work. Of course
the analysis will still be conservative.
> Eg. I think any leaked refs to the data don't qualify (IOW any
> assignment, even if only indirectly via this expression, needs to clear the flag).
If the leaked ref can be shown to be dead, there is no problem. (this is
> One thing the (b) probably /has/ to allow is storing the result in an "auto"
> variable. But making another copy should clear the flag.
> While i originally needed this for immutable/const/mutable, it would also work
> for shared. If spawn() takes a "shared" argument, passing it a "unique" one
> will work too. And i'm not even convinced the ref needs to disappear from the
> current context (obviously accessing the now shared data has to treat it as such
> - but this is not different from what we had before, when using explicit casts;
> in fact now it's marked as "shared" so it should be safer.)
Then you still have to cast away shared in the receiver thread. As I
said before, the idea is that you can send unique objects, not that they
implicitly convert to shared and are then sent.
> So the question is: does having an explicit "unique" storage class improve
> things further?
Yes. Then the concept persists function boundaries. You cannot pass an
unshared object to another thread if there is no explicit unique storage
> Other than using it  to mark things as unique that the compiler can't figure
> out by itself.
>  I'm using "unique", but if it were to become a keyword it should be
> "uniq" or "@uniq", for the same reasons as "int", "auto" or "ref".
>>> And if it can work for "auto" - is an explicit "unique" for 'x' needed?
>>> This example *could* work, but the interesting cases are the ones when the
>>> assignments/mutations are non-trivial and done because the data is actually
>>> used - i'm worried that doing the analysis *then* would be too expensive.
>> I don't think so.
> Consider a container, that you need to verify and/or extract some data from,
> before passing it on to somewhere else. All the accesses before this handover
> happens may indeed be safe and no reference be live anymore. But the compiler
> needs to *prove* this before allowing the conversion to happen.
> This could be very expensive and because it is not an optimization, but a
> correctness issue, the check can *not* be disabled. Every D compiler now has
> to do it, every time.
I think you are overstating the issue. Everything I proposed is quite
cheap to carry out.
More information about the Digitalmars-d