February 27, 2015
On Thursday, 26 February 2015 at 21:07:26 UTC, Andrei Alexandrescu wrote:
> Could you please walk me through what the matter is here. Thanks. -- Andrei

1/ The originating thread is likely to be dead by the time we collect.
2/ The RefCounted Stuff crossed thread boundaries so even if we kept the thread alive somehow to be able to destruct as mentioned, this is still not thread safe.
February 27, 2015
On 2/26/15 7:34 PM, ketmar wrote:
> On Thu, 26 Feb 2015 18:04:28 -0500, Steven Schveighoffer wrote:
>
>>> That's true. However, what if the destructors access global
>>> (thread-local) variables? Is that already disallowed?
>>
>> Hm... I don't know. Is it "disallowed?" I don't think so (a simple test
>> would suffice), but if any code exists today that does it, it's very
>> very wrong :) I would suspect that such code should be banned.
>
> but what if i'm doing memory managing myself and i *know* that it's ok to
> use thread-locals in my destructor?
>

Accessing thread-local data in the GC-run destructor means you are accessing in the GC collecting thread. In the case where we make dtors run in the originating thread, it is OK. But if the thread is gone, then any running of that dtor may incorrectly use the TL data in that thread, which may not be correct.

In any case, accessing thread local data today is most certainly wrong, since there isn't even a likelihood the same thread will destroy the data.

I can't see a situation where this would be what you wanted. Accessing global data should be fine, but thread-local data is not.

-Steve
February 27, 2015
On Thu, 26 Feb 2015 21:56:30 -0500, Steven Schveighoffer wrote:

> On 2/26/15 7:34 PM, ketmar wrote:
>> On Thu, 26 Feb 2015 18:04:28 -0500, Steven Schveighoffer wrote:
>>
>>>> That's true. However, what if the destructors access global (thread-local) variables? Is that already disallowed?
>>>
>>> Hm... I don't know. Is it "disallowed?" I don't think so (a simple test would suffice), but if any code exists today that does it, it's very very wrong :) I would suspect that such code should be banned.
>>
>> but what if i'm doing memory managing myself and i *know* that it's ok to use thread-locals in my destructor?
>>
>>
> Accessing thread-local data in the GC-run destructor means you are accessing in the GC collecting thread. In the case where we make dtors run in the originating thread, it is OK. But if the thread is gone, then any running of that dtor may incorrectly use the TL data in that thread, which may not be correct.
> 
> In any case, accessing thread local data today is most certainly wrong, since there isn't even a likelihood the same thread will destroy the data.
> 
> I can't see a situation where this would be what you wanted. Accessing global data should be fine, but thread-local data is not.

let's assume that i have a program that has only one thread. i know it for sure. and i don't like prepending ugly `__gshared` to my declarations.

sure, it all depends of GC code (it can be multithreaded itself, or it can deliberately run finalisers in another thread), but why i should not be allowed to do what i want? i can write that GC myself, and i *know* that there will be no other threads.

this is the same as allocating in finaliser: as finalisers aren't made implicitly @nogc, i can see no sense in restricting 'em in any other way, as the same arguments applies in both cases.

February 27, 2015
On 2/26/15 10:56 PM, ketmar wrote:
> On Thu, 26 Feb 2015 21:56:30 -0500, Steven Schveighoffer wrote:

>> I can't see a situation where this would be what you wanted. Accessing
>> global data should be fine, but thread-local data is not.
>
> let's assume that i have a program that has only one thread. i know it
> for sure. and i don't like prepending ugly `__gshared` to my declarations.

In that case, you shouldn't be subject to any kind of race conditions. But we can't make the library/language based on this assumption. Your case is the exceptional case.

I think it's going to be difficult to impossible to prevent people from using TLS in destructors anyway. It can probably be a guideline more than a compiler error.

-Steve
February 27, 2015
On Thu, 26 Feb 2015 23:13:01 -0500, Steven Schveighoffer wrote:

> I think it's going to be difficult to impossible to prevent people from using TLS in destructors anyway. It can probably be a guideline more than a compiler error.

and a warning, please! a warning that i can silence, of course.

February 27, 2015
On Thursday, 26 February 2015 at 23:04:28 UTC, Steven Schveighoffer wrote:
> On 2/26/15 4:40 PM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>" wrote:
>> On Thursday, 26 February 2015 at 18:08:28 UTC, Steven Schveighoffer wrote:
>>> On 2/26/15 12:56 PM, "Marc =?UTF-8?B?U2Now7x0eiI=?=
>>> <schuetzm@gmx.net>" wrote:
>>>> On Thursday, 26 February 2015 at 16:51:30 UTC, Steven Schveighoffer
>>>> wrote:
>>>>> As talked about before, running dtors in the originating thread can
>>>>> solve this problem.
>>>>
>>>> This probably implies forcibly destroying objects whose creating thread
>>>> terminated.
>>>
>>> I don't think so, those objects can just be destroyed by the
>>> GC-collection running thread. If the thread is no longer present,
>>> there can't be a race.
>>
>> That's true. However, what if the destructors access global
>> (thread-local) variables? Is that already disallowed?
>
> Hm... I don't know. Is it "disallowed?" I don't think so (a simple test would suffice), but if any code exists today that does it, it's very very wrong :) I would suspect that such code should be banned.

By "disallowed", I indeed mean "banned". Unfortunately, something that's just banned will sooner or later be used by someone, unless it's also statically prevented by the compiler.
February 27, 2015
On Friday, 27 February 2015 at 04:13:03 UTC, Steven Schveighoffer wrote:
> In that case, you shouldn't be subject to any kind of race conditions. But we can't make the library/language based on this assumption. Your case is the exceptional case.
>

His case is not @safe, so we can ignore that problem. However, this do not change the fact that the type qualifier do not provide the guarantee they are supposed to.
February 28, 2015
On Fri, 27 Feb 2015 20:51:54 +0000, deadalnix wrote:

> On Friday, 27 February 2015 at 04:13:03 UTC, Steven Schveighoffer wrote:
>> In that case, you shouldn't be subject to any kind of race conditions. But we can't make the library/language based on this assumption. Your case is the exceptional case.
>>
>>
> His case is not @safe, so we can ignore that problem.

the compiler tends to disagree:

=== test.d ===
int myglobal;

class A {
  ~this () @safe { if (myglobal == 42) assert(0); }
}

void main () {
  auto a = new A;
}
======

dmd -w -c -o- test.d

wow! no warnings, no errors!

February 28, 2015
On Saturday, 28 February 2015 at 04:18:38 UTC, ketmar wrote:
> On Fri, 27 Feb 2015 20:51:54 +0000, deadalnix wrote:
>
>> On Friday, 27 February 2015 at 04:13:03 UTC, Steven Schveighoffer wrote:
>>> In that case, you shouldn't be subject to any kind of race conditions.
>>> But we can't make the library/language based on this assumption. Your
>>> case is the exceptional case.
>>>
>>>
>> His case is not @safe, so we can ignore that problem.
>
> the compiler tends to disagree:
>
> === test.d ===
> int myglobal;
>
> class A {
>   ~this () @safe { if (myglobal == 42) assert(0); }
> }
>
> void main () {
>   auto a = new A;
> }
> ======
>
> dmd -w -c -o- test.d
>
> wow! no warnings, no errors!

Slighty off-topic,
If DIP74 is approved it would be nice if destructors were redesigned(and possibly dropped altogether for non-deterministic lifetimes.)
February 28, 2015
On Saturday, 28 February 2015 at 04:27:36 UTC, weaselcat wrote:
> On Saturday, 28 February 2015 at 04:18:38 UTC, ketmar wrote:
>> On Fri, 27 Feb 2015 20:51:54 +0000, deadalnix wrote:
>>
>>> On Friday, 27 February 2015 at 04:13:03 UTC, Steven Schveighoffer wrote:
>>>> In that case, you shouldn't be subject to any kind of race conditions.
>>>> But we can't make the library/language based on this assumption. Your
>>>> case is the exceptional case.
>>>>
>>>>
>>> His case is not @safe, so we can ignore that problem.
>>
>> the compiler tends to disagree:
>>
>> === test.d ===
>> int myglobal;
>>
>> class A {
>>  ~this () @safe { if (myglobal == 42) assert(0); }
>> }
>>
>> void main () {
>>  auto a = new A;
>> }
>> ======
>>
>> dmd -w -c -o- test.d
>>
>> wow! no warnings, no errors!
>
> Slighty off-topic,
> If DIP74 is approved it would be nice if destructors were redesigned(and possibly dropped altogether for non-deterministic lifetimes.)

Yeah, we should have distinct finalizers (with or without DIP74).