Something needs to happen with shared, and soon.

Regan Heath regan at netmail.co.nz
Mon Nov 12 04:25:20 PST 2012


On Mon, 12 Nov 2012 11:55:51 -0000, Regan Heath <regan at netmail.co.nz>  
wrote:
> On Mon, 12 Nov 2012 02:30:17 -0000, Walter Bright  
> <newshound2 at digitalmars.com> wrote:
>> To make a shared type work in an algorithm, you have to:
>>
>> 1. ensure single threaded access by aquiring a mutex
>> 2. cast away shared
>> 3. operate on the data
>> 4. cast back to shared
>> 5. release the mutex
>
> So what we actually want, in order to make the above "nice" is a  
> "scoped" struct wrapping the mutex and shared object which does all the  
> "dirty" work for you.  I'm thinking..
>
> // (0)
> with(ScopedLock(obj,lock))  // (1)
> {
>    obj.foo = 2;              // (2)
> }                           // (3)
> // (4)
>
> (0) obj is a "shared" reference, lock is a global mutex
> (1) mutex is acquired here, shared is cast away
> (2) 'obj' is not "shared" here so data access is allowed
> (3) ScopedLock is "destroyed" and the mutex released
> (4) obj is shared again
>
> I think most of the above can be done without any compiler support but  
> it would be "nice" if the compiler did something clever with 'obj' such  
> that it knew it wasn't 'shared' inside the the 'with' above.  If not, if  
> a full library solution is desired we could always have another  
> temporary "unshared" variable referencing obj.

There was talk a while back about how to handle the existing object mutex  
and synchronized{} statement blocks and this subject has me thinking back  
to that.  My thinking has gone full circle and rather than bore you with  
all the details I want to present a conclusion which I am hoping is both  
implementable and useful.

First off, IIRC object contains a mutex/monitor/critical section, which  
means all objects contain one.  The last discussion saw many people  
wanting this removed for efficiency.  I propose we do this.  Then, if a  
class or struct is declared as "shared" or a "shared" instance of a class  
or struct is constructed we magically include one (compiler magic which I  
hope is possible).

Secondly I say we make "shared" illegal on basic types.  This is a  
limitation(*) but I believe in most cases a single int is unlikely to be  
shared without an accompanying group of other variables, and usually an  
algorithm operating on those variables.  These variables and the algorithm  
should be encapsulated in a class or struct - which can in turn be shared.

Now.. the synchronized() {} statement can do the magic described above (as  
ScopedLock) for us.  It would be illegal to call it on a non "shared"  
instance.  It would acquire the mutex and cast away "shared" inside the  
block/scope, at the end of the scope it would cast shared back and release  
the mutex.

(*) for those rare cases where a single int or other basic type is all  
that is shared we can provide a wrapper struct which is declared as  
"shared".

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/


More information about the Digitalmars-d mailing list