Shared

Radu void at null.pt
Wed May 15 07:56:12 UTC 2019


On Tuesday, 14 May 2019 at 21:02:10 UTC, Jonathan M Davis wrote:
> On Tuesday, May 14, 2019 8:32:45 AM MDT Radu via Digitalmars-d 
> wrote:
>> On Monday, 13 May 2019 at 16:20:30 UTC, Jonathan M Davis wrote:
>> > On Monday, May 13, 2019 9:52:02 AM MDT Dominikus Dittes 
>> > Scherkl
>> >
>> > via Digitalmars-d wrote:
>> >> [...]
>> >
>> > Actually, it doesn't. All you've done is lock a mutex and 
>> > cast away shared. There is no guarantee that that mutex is 
>> > always used when that object is accessed. There could easily 
>> > be another piece of code somewhere that casts away shared 
>> > without locking anything at the same time. And even if this 
>> > were the only mechanism for removing shared, you could 
>> > easily use it with the same object and a completely 
>> > different mutex in another piece of code, thereby making the 
>> > mutex useless. The type system has no concept of ownership 
>> > and no concept of a mutex being associated with any 
>> > particular object aside from synchronized classes (and those 
>> > don't even currently require that the mutex always be used). 
>> > And even if the compiler could check that all uses of a 
>> > particular variable were locked with a mutex, that still 
>> > wouldn't be enough, because other references to the same 
>> > data could exist. So, with the construct you've proposed, 
>> > there's no way for the compiler to guarantee that no other 
>> > thread is accessing the data at the same time. All it 
>> > guarantees is that a mutex has been locked, not that it's 
>> > actually protecting the data.
>> >
>> > [...]
>>
>> I had this idea for some time, not sure I can best articulated 
>> now, but I think a workable solution for shared is closely 
>> linked with the dip1000 - scoped pointers.
>>
>> What I mean is that something like:
>>
>> void doSharedStuff(scope shared(Foo) foo)
>> {
>> }
>>
>> Will be able to safely lock/unlock foo and cast away 
>> shared'ness
>> in the function's scope.
>> The compiler can provide guarantees here that foo will not 
>> escape.
>
> Sure, it can guarantee that no reference will escape that 
> function, but all that's required is that another reference to 
> the same data exist elsewhere, and another thread could muck 
> with the object while the mutex was locked. There's no question 
> that helpers could be created which would help users avoid 
> mistakes when casting when casting away shared, but the 
> compiler can't actually make the guarantee that casting away 
> shared is thread-safe.
>
> - Jonathan M Davis

My view is that the compiler could automatically insert locking 
logic (ala synchronized) when the shared parameters gets 
references inside the function, and also automatically cast away 
shared so for the function internals it would be like working 
with local non-shared data.

Given that compiler inferes lifetime, it could safely elide 
locking if the parameter is passed to other functions that have 
the same signature (scope is explicit or inferred).

The idea is to provide the tools that simplify concurrent 
programming, the compiler will need to insert all the checks 
automatically using the lifetime tracking.


More information about the Digitalmars-d mailing list