Version française
Home     About     Download     Resources     Contact us    
Browse thread
Finalization and object dependencies
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Florian Weimer <fw@d...>
Subject: Finalization and object dependencies
I've got to different types of objects, say database tables and
cursors for one table.  Caml code is expected to access these objects
using some handle reference.

  * If the GC detects that no handles for a particular cursor exist
    anymore, the underlying cursor object should be closed (which may
    free external resources such as locks).  At this time, all "equal"
    handles become invalid, subsequent operations will fail.

  * If the GC detects that no handles for some table object exist, and
    there are no handles for that table, this table is closed.
    Subsequent operations on "equal" table handles will fail.
    
  * The user may explicitly close a cursor handle.  In this case, the
    underlying object is closed, and the handle is marked invalid.
    (Same as above.)

  * The user may explicitly close a table handle.  In this case, all
    cursor which are still open are closed.  Future operations on
    them, or the table, will fail.

  * When the program exits, all cursors and tables shall be closed,
    even if the program was termined by an exception.

(Here, "to fail" means to raise an exception or some other kind of
deterministic error signaling mechanism.)

Usually, application code will gracefully close all cursors, and the
table, but I want my library to be as safe as possible to use, and
avoid random crashes or memory leaks.

There are a couple of approaches to implement the desired behavior:

  (1) Just use weak arrays of tables and cursor, together with Gc.alarm.

  (2) Use Gc.finalise for handler objects which contain an index into
      (plain) arrays of tables and cursors.  Use reference counting
      (or back pointers) to prevent premature finalization of table
      objects while there are still cursors around.

  (3) Same as (2), but using custom blocks and C code.

  (4) Some hybrid approach.

I'm not exactly happy with each appraoch because it seems I must
implement a simple memory manager on my own for managing the array
elements.  Perhaps I'm missing something?

How is the performance of the three approaches?  Each one uses a
different GC mechanism to achieve its goals, so I'm a bit puzzled.