June 28, 2017 Re: Advice wanted on garbage collection of sockets for c++ programmer using D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Guillaume Piolat | On Wednesday, 28 June 2017 at 00:05:20 UTC, Guillaume Piolat wrote: > On Tuesday, 27 June 2017 at 23:54:50 UTC, Moritz Maxeiner wrote: >> - Replace calls by the GC to `~this` with calls to `finalize` (or invent some cool other shortened name for the latter) > > My point is that in such a "finalize()" function the only sane things to do is to crash if the resource wasn't freed already. Why so? > > [...] Not every class can't be finalized, so it might make sense for finalization to remain an available option. What I think reasonable is treating destruction and finalization as two distinct things. This could look like the following: --- // Does not refer to other GC memory, can be finalized class File { private: int fd; public: this() { fd = open(...); } ~this() { close(fd); } // If the GC collects a File object that hasn't been destroyed yet, it will call this finalizer, // which *manually* calls the destructor (because it's safe to do so in this case) // A File object can still be manually `destroy`ed beforehand, in which case this particular finalizer is still safe, since an object won't be destroyed twice finalize() { destroy(this); } // Or maybe prettier: alias finalize = ~this; } class Foo { private: File f; public: this() { f = new File(); } // Make the process crash on finalization of an undestroyed Foo object @disable finalize(); } --- >> - Reserve `~this` for being called by deterministic lifetime management (std.experimental.allocator.dispose, object.destroy, RefCounted, Unique, etc.) > > That's precisely what the GC-proof-resource-class allows, by preventing defective, non-composable usages of ~this. The GC proof resource class idiom is a necessary hack, but it *is* a hack with its own limitations (e.g. depending on Error being catchable). |
June 27, 2017 Re: Advice wanted on garbage collection of sockets for c++ programmer using D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Moritz Maxeiner | On Wednesday, June 28, 2017 01:11:35 Moritz Maxeiner via Digitalmars-d-learn wrote:
> On Wednesday, 28 June 2017 at 00:05:20 UTC, Guillaume Piolat
>
> wrote:
> > On Tuesday, 27 June 2017 at 23:54:50 UTC, Moritz Maxeiner wrote:
> >> - Replace calls by the GC to `~this` with calls to `finalize` (or invent some cool other shortened name for the latter)
> >
> > My point is that in such a "finalize()" function the only sane things to do is to crash if the resource wasn't freed already. Why so?
> >
> > [...]
>
> Not every class can't be finalized, so it might make sense for finalization to remain an available option.
There are definitely cases where finalizers make sense. Case in point: if you have a socket class, it makes perfect sense for it to have a finalizer. Yes, it's better to close it manually, but it will work just fine for the GC to close it when finalizing the class object so long as you don't use so many sockets that you run out before the GC collects them. So, having a finalizer is a good backup to ensure that the socket resource doesn't leak.
- Jonathan M Davis
|
June 28, 2017 Re: Advice wanted on garbage collection of sockets for c++ programmer using D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Wednesday, 28 June 2017 at 02:13:10 UTC, Jonathan M Davis wrote:
> On Wednesday, June 28, 2017 01:11:35 Moritz Maxeiner via Digitalmars-d-learn wrote:
>> Not every class can't be finalized, so it might make sense for finalization to remain an available option.
>
> There are definitely cases where finalizers make sense. Case in point: if you have a socket class, it makes perfect sense for it to have a finalizer. Yes, it's better to close it manually, but it will work just fine for the GC to close it when finalizing the class object so long as you don't use so many sockets that you run out before the GC collects them. So, having a finalizer is a good backup to ensure that the socket resource doesn't leak.
Yes, I think that's like the File class I presented (at least on Posix).
But on the other hand, since there are also cases in which finalization of an alive (==undestroyed) object are unacceptable (e.g. when it requires other GC managed objects to be alive), splitting them off into two separate methods and allowing to forbid finalization seems sensible to me.
|
June 28, 2017 Re: Advice wanted on garbage collection of sockets for c++ programmer using D | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Burton | On Tuesday, 27 June 2017 at 09:54:19 UTC, John Burton wrote: > I'm coming from a C++ background so I'm not too used to garbage collection and it's implications. I have a function that creates a std.socket.Socket using new and connects to a tcp server, and writes some stuff to it. I then explicitly close the socket, and the socket object goes out of scope. > > [...] May be you can see yu: https://github.com/dushibaiyu/yu |
June 28, 2017 Re: Advice wanted on garbage collection of sockets for c++ programmer using D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 2017-06-27 17:24, Steven Schveighoffer wrote: > Yes, Tango solved this by having a separate "finalize()" method. I wish > we had something like this. Not sure if this is the same, but I remember that Tango had a separate method called "dispose" that was called if a class was allocated on the stack, i.e. with the "scope" keyword. -- /Jacob Carlborg |
June 28, 2017 Re: Advice wanted on garbage collection of sockets for c++ programmer using D | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Burton | On 2017-06-27 11:54, John Burton wrote: > I'm coming from a C++ background so I'm not too used to garbage > collection and it's implications. I have a function that creates a > std.socket.Socket using new and connects to a tcp server, and writes > some stuff to it. I then explicitly close the socket, and the socket > object goes out of scope. Yes. You can use "scope (exit)", unless you're already doing so. > Now the issue is that I now need to call this function more than once > every second. I worry that it will create large amounts of uncollected > "garbage" which will eventually lead to problems. Sounds like you need a connection pool. The vibe.d [1] framework contains connection pools. It's also possible to manually disable the GC for a while and then enable it again. [1] http://vibed.org -- /Jacob Carlborg |
June 28, 2017 Re: Advice wanted on garbage collection of sockets for c++ programmer using D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Wednesday, 28 June 2017 at 02:13:10 UTC, Jonathan M Davis wrote:
> There are definitely cases where finalizers make sense. Case in point: if you have a socket class, it makes perfect sense for it to have a finalizer. Yes, it's better to close it manually, but it will work just fine for the GC to close it when finalizing the class object so long as you don't use so many sockets that you run out before the GC collects them. So, having a finalizer is a good backup to ensure that the socket resource doesn't leak.
>
> - Jonathan M Davis
So far everyone is ignoring my example when A needs B to be destroyed. This happens as soon as you use DerelictUtil for example.
|
June 28, 2017 Re: Advice wanted on garbage collection of sockets for c++ programmer using D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Guillaume Piolat | On Wednesday, 28 June 2017 at 09:16:22 UTC, Guillaume Piolat wrote:
> On Wednesday, 28 June 2017 at 02:13:10 UTC, Jonathan M Davis wrote:
>> There are definitely cases where finalizers make sense. Case in point: if you have a socket class, it makes perfect sense for it to have a finalizer. Yes, it's better to close it manually, but it will work just fine for the GC to close it when finalizing the class object so long as you don't use so many sockets that you run out before the GC collects them. So, having a finalizer is a good backup to ensure that the socket resource doesn't leak.
>>
>> - Jonathan M Davis
>
> So far everyone is ignoring my example when A needs B to be destroyed. This happens as soon as you use DerelictUtil for example.
And I'm gonna rant a little bit more.
Deterministic destruction is a _solved_ problem in C++, and a number of users to convert are now coming from C++.
We should:
1. be honest and tell things as they are: it's more complicated than in C++, but also liberating when you know to juggle between GC and deterministic
2. Avoid making bogus suggestions which don't always work, such as close() methods, releasing resource with GC, . They only work for _some_ resources.
3. Suggest a systematic, always working, workaround (or language change such as "GC doesn't call ~this). C++ users have no difficulty having an object graph with detailed ownership schemes, that's what they do day in day out.
It's important to have a _simple_ story about resource release, else we will talk about "GC" every day, and hearing about "GC" is bad for marketing.
|
June 28, 2017 Re: Advice wanted on garbage collection of sockets for c++ programmer using D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Guillaume Piolat | On Wednesday, 28 June 2017 at 09:16:22 UTC, Guillaume Piolat wrote:
> So far everyone is ignoring my example when A needs B to be destroyed. This happens as soon as you use DerelictUtil for example.
I thought I had (implicitly): B needs to be `@disable finalize`.
|
June 28, 2017 Re: Advice wanted on garbage collection of sockets for c++ programmer using D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Guillaume Piolat | On Wednesday, 28 June 2017 at 09:22:07 UTC, Guillaume Piolat wrote: > Deterministic destruction is a _solved_ problem in C++, and a number of users to convert are now coming from C++. It is also in D, as long as you don't use the GC (which is inherently non-deterministic). > 3. Suggest a systematic, always working, workaround (or language change such as "GC doesn't call ~this). C++ users have no difficulty having an object graph with detailed ownership schemes, that's what they do day in day out. > > It's important to have a _simple_ story about resource release, else we will talk about "GC" every day, and hearing about "GC" is bad for marketing. Requirement: Do not allocate using the GC Option 1) Use structs with `@disable this`, `@disable this(this)`, and a destructor that checks whether the resource reference is != invalid resource reference before trying to release. Option 2) Use classes with simple constructor/destructor layout. If you want to integrate a check that the requirement holds (with either class or struct), put `if (gc_inFinalizer) throw SomeError` into the class/struct destructor |
Copyright © 1999-2021 by the D Language Foundation