<div class="gmail_quote">On Wed, Oct 19, 2011 at 4:11 PM, Michel Fortin <span dir="ltr"><<a href="mailto:michel.fortin@michelf.com">michel.fortin@michelf.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

<div class="im">On 2011-10-19 20:36:37 +0000, Andrew Wiley <<a href="mailto:wiley.andrew.j@gmail.com" target="_blank">wiley.andrew.j@gmail.com</a>> said:<br>
<br>
</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
<br>
On Mon, Oct 17, 2011 at 3:43 PM, Michel Fortin <<a href="mailto:michel.fortin@michelf.com" target="_blank">michel.fortin@michelf.com</a>><u></u>wrote:<br>
<br>
</div><div><div></div><div class="h5"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
On 2011-10-17 20:33:59 +0000, Andrew Wiley <<a href="mailto:wiley.andrew.j@gmail.com" target="_blank">wiley.andrew.j@gmail.com</a>><br>
said:<br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Okay, I realize there have been some discussions about this, but I have a<br>
few questions about shared delegates because right now they are definitely<br>
broken, but I'm not sure how.<br>
Take this code example:<br>
<br>
synchronized class Thing {<br>
void doSomeWork(void delegate() work) {<br>
work();<br>
}<br>
void work() {}<br>
}<br>
<br>
void main() {<br>
auto th = new Thing();<br>
th.doSomeWork(&th.work);<br>
}<br>
<br>
This doesn't compile because the type of "&th.work" is "void delegate()<br>
shared", which cannot be cast implicitly to "void delegate()".<br>
My first question would be whether that type is correct. It's true that<br>
the<br>
data pointer of the delegate points to a shared object, but given that the<br>
function locks it, does that really matter in this case? I guess I'm just<br>
not clear on the exact meaning of "shared" in general, but it seems like<br>
whether the data is shared or not is irrelevant when the delegate points<br>
to<br>
a public member of a synchronized class. If it was a delegate pointing to<br>
a<br>
private/protected member (which should be illegal in this case), that<br>
would<br>
not be true.<br>
If that type is correct, the problem is that "void delegate() shared"<br>
doesn't parse as a type (there is a workaround because you can create<br>
variables of this type through alias and typeof).<br>
<br>
What, exactly, is wrong here?<br>
</blockquote>
<br>
I think what's wrong is that a shared delegate should implicitly convert to<br>
a non-shared one. The delegate is shared since it can be called safely from<br>
any thread, and making it non-shared only prevent you from propagating it to<br>
more thread so it's not harmful in any way.<br>
</blockquote>
<br></div></div><div class="im">
Actually, I've been thinking about this some more, and I think that the<br>
delegate should only implicitly convert if the argument types are safe to<br>
share across threads as well.<br>
</div></blockquote>
<br>
I disagree.<div class="im"><br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
If I had a class that looked like this:<br>
synchronized class Thing2 {<br>
       void doSomeWork(int i) {}<br>
       void doSomeOtherWork(Thing2 t) {}<br>
       void work() {}<br>
}<br>
<br>
The actual argument type in doSomeOtherWork is required to be shared(Thing2)<br>
(which isn't a problem here because Thing2 is a synchronized class, but you<br>
see the point).<br>
</blockquote>
<br></div>
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).<div>

<div></div><div class="h5"><br>
<br></div></div></blockquote><div><br></div><div>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.</div>

<div>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. </div>

</div>