Something needs to happen with shared, and soon.

Manu turkeyman at gmail.com
Thu Nov 15 04:32:47 PST 2012


On 15 November 2012 13:38, Jonathan M Davis <jmdavisProg at gmx.com> wrote:

> On Thursday, November 15, 2012 11:22:30 Manu wrote:
> > Not to repeat my prev post... but in reply to Walter's take on it, it
> would
> > be interesting if 'shared' just added implicit lock()/unlock() methods to
> > do the mutex acquisition and then remove the cast requirement, but have
> the
> > language runtime assert that the object is locked whenever it is accessed
> > (this guarantees the safety in a more useful way, the casts are really
> > annying). I can't imagine a simpler and more immediately useful solution.
> >
> > In fact, it's a reasonably small step to this being possible with
> > user-defined attributes. Although attributes have no current mechanism to
> > add a mutex, and lock/unlock methods to the object being attributed (like
> > is possible in Java/C#), but maybe it's not a huge leap.
>
> 1. It wouldn't stop you from needing to cast away shared at all, because
> without casting away shared, you wouldn't be able to pass it to anything,
> because the types would differ. Even if you were arguing that doing
> something
> like
>
> void foo(C c) {...}
> shared c = new C;
> foo(c); //no cast required, lock automatically taken
>
> it wouldn't work, because then foo could wile away a reference to c
> somewhere,
> and the type system would have no way of knowing that it was a shared
> variable
> that was being wiled away as opposed to a thread-local one, which means
> that
> it'll likely generate incorrect code. That can happen with the cast as
> well,
> but at least in that case, you're forced to be explicit about it, and it's
> automatically @system. If it's done for you, it'll be easy to miss and
> screw
> up.
>

I don't really see the difference, other than, as you say, the cast is
explicit.
Obviously the possibility for the situation you describe exists, it's
equally possible with the cast, except this way, the usage pattern is made
more convenient, the user has a convenient way to control the locks and
most importantly, it would work with templates.
That said, this sounds like another perfect application of 'scope'. Perhaps
only scope parameters can receive a locked, shared thing... that would
mechanically protect you against escape.

2. It's often the case that you need to lock/unlock groups of stuff together
> such that locking specific variables is of often of limited use and would
> just
> introduce pointless extra locks when dealing with multiple variables. It
> would
> also increase the risk of deadlocks, because you wouldn't have much - if
> any -
> control over what order locks were acquired in when dealing with multiple
> shared variables.


Your fear is precisely the state we're in now, except it puts all the work
on the user to create and use the synchronisation objects, and also to
assert that things are locked when they are accessed.
I'm just suggesting some reasonably simple change that would make the
situation more usable and safer immediately, short of waiting for all these
fantastic designs being discussed having time to simmer and manifest.

Perhaps a usage mechanism could be more like:
shared int x, y, z;
synchronised with(x, y, z)
{
  // do work with x, y, z, all locked together.
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20121115/2f1cd8fe/attachment-0001.html>


More information about the Digitalmars-d mailing list