auto classes and finalizers

kris foo at bar.com
Sun Apr 9 21:10:51 PDT 2006


Dave wrote:
> 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
> 
> 

See post entitled "GC & dtors ~ a different approach" at 6:17pm ?



More information about the Digitalmars-d mailing list