Acquiring and releasing resources

Home
Introduction
Tips and Techniques
Projects
Libraries
Links

Sometimes you need to take ownership of some sort of resource and release ownership when you've completed your work with it. Examples of this are:

  • Opening a file, writing to it and closing it.
  • Taking ownership of a mutex, doing some work then releasing the mutex.

In C++ you can use constructors and destructors to do this and the idiom is commonly called the resource acquisition is initialisation idiom. In languages like Dylan that don't have explicit stack based objects you cannot do this.

One method is to use garbage collection and finalisers. You obtain control of the resouce when constructing an object and release it in the finaliser. The problem with this is there is no guarantee when the finaliser method will be called - if at all.

The solution is to use blocks. Dylan provides the cleanup clause in blocks to ensure that resources are released. A cleanup clause will always be executed even if an exception is signalled within the block. The body of the cleanup clause is executed at the end of the block regardless of completion or failure of statements within the block. For example:

   let resource = obtain-resource();
   block()
     do-something(resource);
   cleanup
     release-resource(resource);
   end;

If anything goes wrong within the body of the block above you can still be sure that the resource will be released. In the presence of exceptions (and other forms of non local transfer of control) this functionality is very important.

When there is the need to do this type of thing frequently it is common to create a macro to simplify useage and make the intent in the code explicit. A macro to perform the example above would be:

   define macro with-resource
      { with-resource (?resource:variable) ?:body end }
        => { begin
                let ?resource = obtain-resource();
                block()
                   ?body
                cleanup
                   release-resource(?resource);
                end;
             end }
   end macro;

   // Useage
   with-resource(resource)
     do-something(resource);
   end;

Examples of this type of idiom in Dylan libraries are the macro with-open-file and the DUIM macro with-busy-cursor.


Copyright © 2000, Chris ^M Double. All Rights Reserved.
^M All products and brand names are the registered trademarks or trademarks ^M of their respective owners.

^M