Jump to page: 1 2
Thread overview
Finalizers, Destructors, RAII, GC
Apr 28, 2021
Guillaume Piolat
Apr 28, 2021
12345swordy
Apr 28, 2021
12345swordy
Apr 28, 2021
12345swordy
Apr 29, 2021
Imperatorn
Apr 30, 2021
Max Haughton
Apr 28, 2021
Kagamin
Apr 29, 2021
Kagamin
Apr 28, 2021
sighoya
April 28, 2021
It is currently an issue that people might write a class for RAII and then allocate in on the GC heap, that means that destructors can be called in the wrong order.

If D adds a finalizer() method, this could be resolved the following way:

Objects with non-empty destructors cannot be GC allocated.

The finalizer() method should be used for releasing all non-GC resources accessible from non-GC pointers/identifiers, but one should not follow pointers to GC-memory from a finalizer as they may not exist.

So a RAII object needs to call the finalizer from the destructor, but exactly what would the implications be for inheritance?

Anyway, if it isn't clear, the basic goal is to allow RC-based RAII and GC to coexist.

Or would it be better to simply forbid any cleanup in the GC? I kinda think so, but I also think many D users are used to letting the GC trigger cleanup on collection.

What do you think?

April 28, 2021
On Wednesday, 28 April 2021 at 10:04:20 UTC, Ola Fosheim Grøstad wrote:
>
> Or would it be better to simply forbid any cleanup in the GC?

Yes and I think Andrei defended the idea years ago, and it was shutdown by the ensuing discussion.

With GC.inFinalizer you can use the GC as a detector of accidental correctness, so the current state is not that bad. It's just more complicated than needed.
April 28, 2021
On Wednesday, 28 April 2021 at 11:13:52 UTC, Guillaume Piolat wrote:
> With GC.inFinalizer you can use the GC as a detector of accidental correctness, so the current state is not that bad. It's just more complicated than needed.

But it is also memory unsafe isn't it?

If @safe is to be a meaningful concept it should at least be guaranteed for naive users who don't do anything fancy and rely on the GC for all allocations.

April 28, 2021

On Wednesday, 28 April 2021 at 10:04:20 UTC, Ola Fosheim Grøstad wrote:

>

It is currently an issue that people might write a class for RAII and then allocate in on the GC heap, that means that destructors can be called in the wrong order.

If D adds a finalizer() method, this could be resolved the following way:

Objects with non-empty destructors cannot be GC allocated.

The finalizer() method should be used for releasing all non-GC resources accessible from non-GC pointers/identifiers, but one should not follow pointers to GC-memory from a finalizer as they may not exist.

So a RAII object needs to call the finalizer from the destructor, but exactly what would the implications be for inheritance?

Anyway, if it isn't clear, the basic goal is to allow RC-based RAII and GC to coexist.

Or would it be better to simply forbid any cleanup in the GC? I kinda think so, but I also think many D users are used to letting the GC trigger cleanup on collection.

What do you think?

Split the finalizer from the destructor and make the finalizer an interface.

-Alex

April 28, 2021
On Wednesday, 28 April 2021 at 14:43:24 UTC, 12345swordy wrote:
> Split the finalizer from the destructor and make the finalizer an interface.

Interfaces are expensive. I think it could be in the vtable. It should also support inheritance.

One should be able to inherit a superclass which has a finalizer that supports GC and then make a RAII subclass from it.

There is also a need to annotate pointers which are known to not point to GC memory, maybe @nogc could be reused for that. Then you would only be allowed to read @nogc pointers within a finalizer.



April 28, 2021
On Wednesday, 28 April 2021 at 10:04:20 UTC, Ola Fosheim Grøstad wrote:
> Anyway, if it isn't clear, the basic goal is to allow RC-based RAII and GC to coexist.

You want synchronized RC?
April 28, 2021
On Wednesday, 28 April 2021 at 16:12:37 UTC, Kagamin wrote:
> On Wednesday, 28 April 2021 at 10:04:20 UTC, Ola Fosheim Grøstad wrote:
>> Anyway, if it isn't clear, the basic goal is to allow RC-based RAII and GC to coexist.
>
> You want synchronized RC?

For shared, but not for nonshared?


April 28, 2021
On Wednesday, 28 April 2021 at 15:17:01 UTC, Ola Fosheim Grøstad wrote:
> On Wednesday, 28 April 2021 at 14:43:24 UTC, 12345swordy wrote:
>> Split the finalizer from the destructor and make the finalizer an interface.
>
> Interfaces are expensive. I think it could be in the vtable. It should also support inheritance.
>
> One should be able to inherit a superclass which has a finalizer that supports GC and then make a RAII subclass from it.
>
> There is also a need to annotate pointers which are known to not point to GC memory, maybe @nogc could be reused for that. Then you would only be allowed to read @nogc pointers within a finalizer.

How on earth are interfaces expensive?


-Alex

April 28, 2021
On Wednesday, 28 April 2021 at 21:12:08 UTC, 12345swordy wrote:
> How on earth are interfaces expensive?

Look at the implementation?

April 28, 2021
On Wednesday, 28 April 2021 at 10:04:20 UTC, Ola Fosheim Grøstad wrote:
> It is currently an issue that people might write a class for RAII and then allocate in on the GC heap, that means that destructors can be called in the wrong order.
>
> If D adds a finalizer() method, this could be resolved the following way:
>
> Objects with non-empty destructors cannot be GC allocated.
>
> The finalizer() method should be used for releasing all non-GC resources accessible from non-GC pointers/identifiers, but one should not follow pointers to GC-memory from a finalizer as they may not exist.

Doesn't suffice ownership here? I mean you surely talk about owned manually allocated memory inside a class.
But why the need at all for a finalizer and instead allow non-empty destructors for gc allocated classes?
Having both is confusing.

> Or would it be better to simply forbid any cleanup in the GC? I kinda think so, but I also think many D users are used to letting the GC trigger cleanup on collection.
>
> What do you think?

Probably not for gc managed resources, but what about making class members reference counted or owned instead. Owned resources should be deleted automatically when a class object is destructed and reference counted resources are deleted if refcount goes to zero, which may occurs after destruction but at least not before.

Btw, I don't know how much is currently possible in D.
« First   ‹ Prev
1 2