Shared Delegates

Michel Fortin michel.fortin at michelf.com
Wed Oct 19 14:11:02 PDT 2011


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).


-- 
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/



More information about the Digitalmars-d mailing list