auto BufferedFile keeps file locked

kris foo at bar.com
Fri Apr 21 11:48:50 PDT 2006


Ben Hinkle wrote:
> "Lionello Lunesu" <lio at lunesu.remove.com> wrote in message 
> news:e2akhb$2au3$1 at digitaldaemon.com...
> 
>>Hi,
>>
>>Been playing around with the stream classes in Phobos some more and I've 
>>noticed the following:
>>
>>#void bla( char[] fn ) {
>>#  auto BufferedFile bf = new BufferedFile;
>>#  bf.open(fn);
>>#}
>>
>>After calling the function "bla", the opened file remains locked. Adding 
>>"bf.close" at the end of the function correctly closes the file and does 
>>not keep the file locked. Using "File" instead of "BufferedFile" also 
>>solves the problem.
>>
>>After thinking about it for half an hour I finally got it: the 
>>BufferedFile, which had a reference to a File instance, got destructed 
>>like it should but the File's not being collected together with the 
>>BufferedFile.
>>
>>It seems the File instance inside BufferedFile should be linked somehow to 
>>the BufferedFile instance.
>>
>>Would adding a destructor to BufferedFile solve the problem?
>>
>>#class BufferedFile: BufferedStream {
>>#
>>#  // opens file for reading
>>#  this() { super(new File()); }
>>#  ~this() { close(); }
>>...
> 
> 
> An object's destructor cannot refer to any other gc-managed resource. In 
> particular the BufferedFile's destructor cannot close the associated File. 
> See the help section about garbage collection for more info. With the 
> current language design there is no way to have a 'auto' class clean up more 
> than just itself. For example by the time the BufferedFile destructor runs 
> the buffer used to hold the data of the BufferedFile might be gone and 
> unreachable.
> 
> 
>>L.
>>
>>PS. Who else thinks it should be "BufferFile" (and not "BufferedFile"; 
>>(analogous to "FilterStream" and not "FilteredStream")? 
> 
> 
> 


This is exactly the kind of problem discussed in the "auto classes and 
finalizers" thread. Due to the "unspecified" state (of references) when 
a dtor is called by the GC, one cannot, as a general rule use a dtor to 
clean up -- if you 'forget' to delete or raii it, the GC will collect 
the class and the example dtor (above) will currently GPF.

This situation encourages the use of dispose()/close() instead, which is 
arguably the wrong approach. The Ares runtime library now has support 
for controlling the behaviour of collections upon dtors.



More information about the Digitalmars-d-learn mailing list