auto classes and finalizers
Regan Heath
regan at netwin.co.nz
Sun Apr 9 21:08:02 PDT 2006
On Sun, 09 Apr 2006 19:27:09 -0700, kris <foo at bar.com> wrote:
> Regan Heath wrote:
>> On Sun, 09 Apr 2006 18:34:47 -0700, kris <foo at bar.com> wrote:
>>
>>> Mike Capp wrote:
>>>
>>>> In article <e1c6vl$moj$1 at digitaldaemon.com>, kris says...
>>>>
>>>>> I think we can safely put aside the entire-program-as-one-function
>>>>> as unrealistic. Given that, and assuming the existance of a dtor
>>>>> implies "auto" (and thus raii), how does one manage a "pool" of
>>>>> resources? For example, how about a pool of DB connections? Let's
>>>>> assume that they need to be correctly closed at some point, and
>>>>> that the pool is likely to expand and contract based upon demand
>>>>> over time ...
>>>>>
>>>>> So the question is how do those connections, and the pool itself,
>>>>> jive with scoped raii? Assuming it doesn't, then one would
>>>>> presumeably revert to a manual dispose() pattern with such things?
>>>>
>>>> Two different classes. A ConnectionPool at application scope, e.g.
>>>> in main(),
>>>> and a ConnectionUsage wherever you need one. Both are RAII.
>>>> ConnectionPool acts
>>>> as a factory for ConnectionUsage instances (modulo language
>>>> limitations) and
>>>> adds to the pool as needed; ConnectionUsage just "borrows" an
>>>> instance from the
>>>> pool for the duration of its scope.
>>>> cheers
>>>> Mike
>>>
>>>
>>> Thanks!
>>>
>>> So, when culling the pool (say, on a timeout basis) the cleanup-code
>>> for the held resource is not held within the "borrowed" dtor, but in
>>> a dispose() method? Otherwise, said dtor would imply raii for the
>>> borrowed connection, which would be bogus behaviour for a class
>>> instance that is being held onto by the pool? In other words: you'd
>>> want to avoid deleting (via raii) the connection object, so you'd
>>> have to be careful to not use a dtor in such a case (if we assume
>>> dtor means raii).
>> Unless you add a 'shared' keyword as I described in a previous post.
>> eg.
>> auto class Connection { //auto required to have dtor
>> HANDLE h;
>> ~this() { CloseHandle(h); }
>> }
>> class ConnectionUsage {
>> shared Connection c;
>> }
>> ConnectionUsage is not required to be 'auto' because it has no 'auto'
>> class members which are not 'shared' resources. Alternately you
>> implement reference counting for the Connection class, remove shared,
>> and add 'auto' to ConnectionUsage.
>> Regan
>
> Yes ~ that's true.
>
> On the other hand, all these concerns would melt away if the GC were
> changed to not invoke the dtor (see related post). The beauty of that
> approach is that there's no additional keywords or compiler behaviour;
True, however the beauty is marred by the possibility of resource leaks.
I'd like to think we can come up with a solution which prevents them, or
at least makes them less likely. It would be a big step up over C++ etc
and if it takes adding a keyword and/or new compiler behaviour it's a
small price to pay IMO.
> only the GC is modified to remove the dtor call during a normal
> collection cycle. Invoking delete or raii just works as always, yet the
> invalid dtor state is eliminated. It also eliminates the need for a
> dispose() pattern, which would be nice ;-)
At least this idea stops people doing things they shouldn't in dtors.
What I think we need to do is come up with several concrete use-cases
(actual code) which use resources which need to be released and explore
how each suggestion would affect that code, for example I'm still not
conviced the linklist use-case mentioned here several times requires any
explicit cleanup code, isn't it all just memory to be freed by the GC? Can
someone post a code example and explain why it does please.
It seems to me that as modules already have ctor/dtors then my suggestion
can simply treat a module like a class i.e. automatically adding a dtor
(or appending to an existing dtor) which deletes the (non shared) auto
class instances at module level.
Regan
More information about the Digitalmars-d
mailing list