<div dir="ltr"><div dir="ltr">On Tue, Aug 4, 2020 at 11:55 PM Sebastiaan Koppe via Digitalmars-d <<a href="mailto:digitalmars-d@puremagic.com">digitalmars-d@puremagic.com</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Tuesday, 4 August 2020 at 12:52:01 UTC, Manu wrote:<br>
> On Tue, Aug 4, 2020 at 5:40 PM Sebastiaan Koppe via <br>
> Digitalmars-d < <a href="mailto:digitalmars-d@puremagic.com" target="_blank">digitalmars-d@puremagic.com</a>> wrote:<br>
>> There is just one thing about shared I don't understand. If I <br>
>> design my object such that the non-shared methods are to be <br>
>> used thread-local and the shared methods from any thread, it <br>
>> follows that I should be able to call said shared methods from <br>
>> both a shared and non-shared instance of that object.<br>
><br>
> Yes, this is a thing I talked at great length 1-2 years ago.<br>
> If you take shared to mean "is thread-safe", then my idea was <br>
> that<br>
> not-shared -> shared implicit conversion should be possible.<br>
> What I often do is this:<br>
><br>
> struct Thing<br>
> {<br>
>   ref shared(Thing) implSharedCast() { return <br>
> *cast(shared)&this; }<br>
>   alias implSharedCast this;<br>
> }<br>
><br>
> If that were an implicit conversion, that implies a slight <br>
> change of<br>
> meaning of shared (to one that I consider immensely more <br>
> useful), but it's<br>
> more challenging for the compiler to prove with confidence, and <br>
> there's a<br>
> lot of resistance to this change.<br>
<br>
What exactly does the compiler need to prove?</blockquote><div><br></div><div>It would be ideal if the compiler could validate that the un-shared methods are safe with respect to any shared methods.</div><div>If a shared (ie, 'thread-safe') method were called in parallel to an un-shared method as is possible if the implicit conversion was allowed, then it is necessary that un-shared methods need to be tolerant of their 'thread-safe' API being called at any time. That's the change in meaning which is highly dangerous without some serious tooling. Essentially, adding a shared method to an object applies a contract to all other NOT-shared methods, and that doesn't feel good; "touching this here affects those other things"... it will be super hard to audit.</div><div><br></div><div>Technology that looks like ThreadSanitizer might help, but it gets more tricky again when UFCS is used instead of member functions; those associations are harder to track.</div><div></div><div><br></div><div>I think that idea is doomed, and more recently I'm thinking about ways to prevent sneaking un-shared aliases across the conversion boundary... but I don't know how to achieve that without some sort of aliasing rules which seem unlikely.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">The restrictions <br>
are all in place, you can only call shared methods on a shared <br>
object, and you can only access shared members in a shared method.<br></blockquote><div><br></div><div>Ummmm no, under any of my proposals, you can't access shared members in a shared method... a shared method's `this` pointer is shared, which means all members are shared, and shared data may not be read or written at all... shared methods have no @safe access to members. They can only call other shared methods <a class="gmail_plusreply" id="plusReplyChip-1">@safe-ly.</a></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Hmm, well I guess if members themselves were also implicitly <br>
promoted to shared that could cause havoc.<br></blockquote><div><br></div><div>Members inherit the qualifier of methods... in a shared method, members are shared, which means you can't read or write them.</div></div></div>