Shared Delegates

Andrew Wiley wiley.andrew.j at gmail.com
Wed Oct 19 14:53:12 PDT 2011


On Wed, Oct 19, 2011 at 4:11 PM, Michel Fortin <michel.fortin at michelf.com>wrote:

> On 2011-10-19 20:36:37 +0000, Andrew Wiley <wiley.andrew.j at gmail.com>
> said:
>
>
>> On Mon, Oct 17, 2011 at 3:43 PM, Michel Fortin <michel.fortin at michelf.com
>> >**wrote:
>>
>>  On 2011-10-17 20:33:59 +0000, Andrew Wiley <wiley.andrew.j at gmail.com>
>>> said:
>>>
>>>
>>>  Okay, I realize there have been some discussions about this, but I have
>>>> a
>>>> few questions about shared delegates because right now they are
>>>> definitely
>>>> broken, but I'm not sure how.
>>>> Take this code example:
>>>>
>>>> synchronized class Thing {
>>>> void doSomeWork(void delegate() work) {
>>>> work();
>>>> }
>>>> void work() {}
>>>> }
>>>>
>>>> void main() {
>>>> auto th = new Thing();
>>>> th.doSomeWork(&th.work);
>>>> }
>>>>
>>>> This doesn't compile because the type of "&th.work" is "void delegate()
>>>> shared", which cannot be cast implicitly to "void delegate()".
>>>> My first question would be whether that type is correct. It's true that
>>>> the
>>>> data pointer of the delegate points to a shared object, but given that
>>>> the
>>>> function locks it, does that really matter in this case? I guess I'm
>>>> just
>>>> not clear on the exact meaning of "shared" in general, but it seems like
>>>> whether the data is shared or not is irrelevant when the delegate points
>>>> to
>>>> a public member of a synchronized class. If it was a delegate pointing
>>>> to
>>>> a
>>>> private/protected member (which should be illegal in this case), that
>>>> would
>>>> not be true.
>>>> If that type is correct, the problem is that "void delegate() shared"
>>>> doesn't parse as a type (there is a workaround because you can create
>>>> variables of this type through alias and typeof).
>>>>
>>>> What, exactly, is wrong here?
>>>>
>>>
>>> I think what's wrong is that a shared delegate should implicitly convert
>>> to
>>> a non-shared one. The delegate is shared since it can be called safely
>>> from
>>> any thread, and making it non-shared only prevent you from propagating it
>>> to
>>> more thread so it's not harmful in any way.
>>>
>>
>> Actually, I've been thinking about this some more, and I think that the
>> delegate should only implicitly convert if the argument types are safe to
>> share across threads as well.
>>
>
> I disagree.
>
>
>
>  If I had a class that looked like this:
>> synchronized class Thing2 {
>>       void doSomeWork(int i) {}
>>       void doSomeOtherWork(Thing2 t) {}
>>       void work() {}
>> }
>>
>> The actual argument type in doSomeOtherWork is required to be
>> shared(Thing2)
>> (which isn't a problem here because Thing2 is a synchronized class, but
>> you
>> see the point).
>>
>
> Is it? Whether the argument was shared or not, the thread in which the
> function code runs can only access thread-local data from that thread,
> including the arguments and global variables. It won't be able to send
>  references to non-shared data to other threads just because its context
> pointer is shared (or synchronized).
>
>
>
The problem is that what's behind the context pointer is also shared. If
this delegate is just a closure, that doesn't matter, since the context is
basically immutable.
The problem I see is when the delegate is actually a member function that
stores data in an object. If it was passed a reference to non-shared data,
it could store that reference in a shared object, breaking transitive
shared.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20111019/ed81a900/attachment-0001.html>


More information about the Digitalmars-d mailing list