On Wednesday, 19 July 2017 at 20:23:18 UTC, Jonathan M Davis
wrote:
On Wednesday, July 19, 2017 2:29:04 PM MDT Atila Neves via
Digitalmars-d wrote:
On Tuesday, 18 July 2017 at 19:24:18 UTC, Jonathan M Davis
wrote:
> On Tuesday, July 18, 2017 18:06:56 Atila Neves via
>> Except for a programmer explicitly and manually calling the
>> destructor (in which case, don't), the destructor is only
>> ever called by one thread.
>
> It could still be a problem if the struct has a member
> variable that is a reference type, because then something
> else could refer to that object, and if it's shared, then
> you would need to protect it, and the operations that shared
> prevents should still be prevented. For full-on value types,
> it should be a non-issue though.
>
> - Jonathan M Davis
Mmm, I guess so. As Marco pointed out, it's a similar problem
with immutable (because the compiler casts it away before
calling the destructor).
Although I dare say that anybody writing code that depends on
such locking and destruction when shared is unlikely to get it
right in the first place.
Well, consider that something like a reference counted type
would have to get this right. Now, a reference counted type
that worled with shared would need to be written that way -
simply slapping shared on such a smart pointer type isn't going
to work - but it would then be really bad for the destructor to
be treated as thread-local.
Not necessarily - the reference counted smart pointer doesn't
have to be `shared` itself to have a `shared` payload. I'm not
even entirely sure what the advantage of it being `shared` would
be, or even what that would really mean.
The way `automem.RefCounted` works right now is by doing atomic
reference count manipulations by using reflection to know if the
payload is `shared`.
It really looks to me like having a thread-local dstructor for
shared data is just begging for problems. It may work in the
simple cases, but it'll fall apart in the more complicated
ones, and I don't see how that's acceptable.
You've definitely made me wonder about complicated cases, but I'd
argue that they'd be rare. Destructors are (bar manually calling
them) run in one thread. I'm having trouble imagining a situation
where two threads have references to a `shared` object/value that
is going to be destroyed deterministically.
Only really basic types are going to work as shared without
being specifically designed for it, so I'm inclined to think
that it would be far better for the language to be changed so
that it supports having both a shared and non-shared destructor
rather than having shared objects work with non-shared
destructors.
Perhaps.
Atila