auto classes and finalizers

Dave Dave_member at pathlink.com
Sun Apr 9 20:01:47 PDT 2006


In article <e1cfpo$100u$1 at digitaldaemon.com>, kris says...
>
>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; 
>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 ;-)

So, 'auto' and delete would work as they do now, with the remaining problem of
people defining ~this() and it (inadvertently) never gets called, even at
program exit?

Hmmm if that's so, I'd add one thing -- how about something like a
"fullCollect(bool finalize = false)" that would be called with 'true' at the end
of dmain(), and could be explicitly called by the programmer?

That could run into the problem of dtors invoked in an invalid state, but at
least then it would still be deterministic (either the program ending normally
or the programmer calling fullCollect(true)).

BTW - I must have missed it, but what would be an example of a dtor called in an
invalid state?

Thanks,

- Dave





More information about the Digitalmars-d mailing list