Very limited shared promotion

Jonathan M Davis newsgroup.d at jmdavisprog.com
Mon Jun 24 23:56:52 UTC 2019


On Monday, June 24, 2019 4:06:03 PM MDT aliak via Digitalmars-d wrote:
> On Monday, 24 June 2019 at 13:20:23 UTC, Jonathan M Davis wrote:
> > However, one issue with that from a usability perspective is
> > that even if you're doing all of the right stuff like
> > protecting access to the shared variable via a mutex and then
> > temporarily casting it to thread-local to operate on it while
> > the mutex is locked, if you want to actually assign anything to
> > the shared variable before releasing the mutex, you'd have to
> > use a pointer to it that had been cast to thread-local, whereas
> > right now, you're actually allowed to just assign to it. e.g.
> >
> > shared MyClass obj;
> >
> > synchronized(mutex)
> > {
> >
> >     obj = cast(shared)someObj;
> >
> > }
> >
> > works right now, but if writing to shared variables were
> > illegal like it arguably should be, then you'd have to do
> > something ugly like
> >
> > shared MyClass obj;
> >
> > synchronized(mutex)
> > {
> >
> >     auto ptr = cast(MyClass*)&obj;
> >     *ptr = someObj;
> >
> > }
>
> You can have the same usability/aesthetics:
>
> synchronized {
>    cast(MyClass)obj = someObj;
> }
>
> Doesn't that work?

I've never seen a cast used in that manner. It's been my understanding that
casts always result in rvalues, but it's quite possible that your example
works, and I've just made a wrong assumption about how casts work with
regards to lvalues. Right or wrong though, I'm not the only one who has
thought that, since this issue has been brought up before. But even if it
doesn't work, it would be a possible improvement to make dealing with shared
more palatable.

> Ideally though, I think you'd want:
>
> class MyClass {
>    void opAssign(MyClass c) shared { ... }
> }

Sure, but if you're doing that, that means that the class itself is handling
its own synchronization, which doesn't work in all cases, and even if it
did, it's just pushing the problem into the class. The implementation for
opAssign is going to have deal with assigning to types that don't have
shared opAssign where either atomic writes or mutexes with casts or whatnot
are going to be needed. In general, encapsulating such code is great where
possible, but at some point, the built-in types are going to need to be
manipulated, and if the type is a user-defined type that's designed to be
thread-local but works as shared with mutexes and casts, then it's not going
to have a shared opAssign any more than an int or string will. So, such an
opAssign is just encapsulating the problem, not making it go away.

- Jonathan M Davis





More information about the Digitalmars-d mailing list