On Thu, Oct 18, 2018 at 12:15 PM Steven Schveighoffer via
Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On 10/18/18 2:55 PM, Manu wrote:
> > On Thu, Oct 18, 2018 at 7:20 AM Steven Schveighoffer via Digitalmars-d
> > <digitalmars-d@puremagic.com> wrote:
> >>
> >> On 10/18/18 10:11 AM, Simen Kjærås wrote:
> >>> On Thursday, 18 October 2018 at 13:35:22 UTC, Steven Schveighoffer wrote:
> >>>> struct ThreadSafe
> >>>> {
> >>>>     private int x;
> >>>>     void increment()
> >>>>     {
> >>>>        ++x; // I know this is not shared, so no reason to use atomics
> >>>>     }
> >>>>     void increment() shared
> >>>>     {
> >>>>        atomicIncrement(&x); // use atomics, to avoid races
> >>>>     }
> >>>> }
> >>>
> >>> But this isn't thread-safe, for the exact reasons described elsewhere in
> >>> this thread (and in fact, incorrectly leveled at Manu's proposal).
> >>> Someone could write this code:
> >>>
> >>> void foo() {
> >>>       ThreadSafe* a = new ThreadSafe();
> >>>       shareAllOver(a);
> >>
> >> Error: cannot call function shareAllOver(shared(ThreadSafe) *) with type
> >> ThreadSafe *
> >
> > And here you expect a user to perform an unsafe-cast (which they may
> > not understand), and we have no language semantics to enforce the
> > transfer of ownership. How do you assure that the user yields the
> > thread-local instance?
>
> No, I expect them to do:
>
> auto a = new shared(ThreadSafe)();

I don't have any use for this design in my application.
I can't use the model you prescribe, at all.

> > I think requiring the cast is un-principled in every way that D values.
>
> No cast is required. If you have shared data, it's shared. If you have
> thread local data, it's unshared. Allocate the data the way you expect
> to use it.

All data is thread-local, and occasionally becomes shared during periods.
I can't make use of the model you describe.

My proposal is more permissive, and allows a wider range of
application designs. What are the disadvantages?

> It's only if you intend to turn unshared data into shared data where you
> need an unsafe cast.

It's unnecessary though, because threadsafe functions are threadsafe!
You're pointlessly forcing un-safety. Why would I prefer a design that
forces unsafe interactions to perform safe operations?

> It's not even as difficult as immutable, because you can still modify
> shared data. For instance, the shared constructor doesn't have to have
> special rules about initialization, it can just assume shared from the
> beginning.

Your design us immutable, mine is const.
Tell me, how many occurrences of 'immutable' can you find in your
software? ... how about const?
Which is more universally useful? If you had to choose one or the
other, which one could you live without?

Reply via email to