s c h e m a t i c s : c o o k b o o k

/ Cookbook.PLTCustodianRegistration

This Web


WebHome 
WebChanges 
TOC (with recipes)
NewRecipe 
WebTopicList 
WebStatistics 

Other Webs


Chicken
Cookbook
Erlang
Know
Main
Plugins
Sandbox
Scm
TWiki  

Schematics


Schematics Home
Sourceforge Page
SchemeWiki.org
Original Cookbook
RSS

Scheme Links


Schemers.org
Scheme FAQ
R5RS
SRFIs
Scheme Cross Reference
PLT Scheme SISC
Scheme48 SCM
MIT Scheme scsh
JScheme Kawa
Chicken Guile
Bigloo Tiny
Gambit LispMe
GaucheChez

Lambda the Ultimate
TWiki.org

Registering an object to a custodian

Problem

The foreign function interface allows us to register objects with a finalizer that calls when an object is about to be GC-ed. However, there are certain resources that we'd like to reclaim in a controlled way. For example, if the object lives to the end of the Scheme session, no GC will ever happen on it. PLT Scheme provides custodians to do this resource management. This module includes a nice register-custodian primitive that's similar to register-finalizer. Please also note that an object can have both a finalizer and a custodian (must be weakly held by the custodian in this case to allow the finalizer to run), so you can have fine control on it.

Solution

#lang scheme/base

(require scheme/foreign
         (only-in '#%foreign ffi-callback))
(unsafe!)

(define-values (add-managed remove-managed)
  (letrec ((add
            (get-ffi-obj "scheme_add_managed" #f
                         (_fun (_pointer = #f) _scheme (_fpointer = callback) (_pointer = #f) _bool -> _pointer)))
           (remove
            (get-ffi-obj "scheme_remove_managed" #f
                         (_fun _pointer _scheme -> _void)))
           (gc-ptr-ok
            (get-ffi-obj "scheme_gc_ptr_ok" #f
                         (_fun _scheme -> _void)))
           (dont-gc-ptr
            (get-ffi-obj "scheme_dont_gc_ptr" #f
                         (_fun _scheme -> _void)))
           (callback
            (ffi-callback (lambda (object _)
                            (gc-ptr-ok callback)
                            (gc-ptr-ok gc-ptr-ok)
                            (gc-ptr-ok MyClose)
                            (MyClose object))
                          (list _scheme _pointer) _void
                          #f #t)))
    (values (lambda (o)
              (dont-gc-ptr callback)
              (dont-gc-ptr gc-ptr-ok)
              (dont-gc-ptr MyClose)
              (add o))
            (lambda (ref o)
              (gc-ptr-ok callback)
              (gc-ptr-ok gc-ptr-ok)
              (gc-ptr-ok MyClose)
              (remove ref o)))))

Discussion

The code here is designed to hold any number of objects with the same type. The undefined `MyClose' is the Scheme function that should do the actual job to close the object. The C callback is only generated once for all of the objects. If you only have one object to register, things can be simplified. `scheme_gc_ptr_ok' and `scheme_dont_gc_ptr' are needed to keep the C callback from being GCed before all the registered objects are shut down. If you also use a finalizer on the object, or if one object is manually closed before the custodian shuts it down, remember to call `remove-managed' to remove the object from the custodian.


Comments about this recipe

Contributors

-- DannyYoo - 03 Oct 2005 -- ChongkaiZhu? - 07 Dec 2009

 
 
Copyright © 2004 by the contributing authors. All material on the Schematics Cookbook web site is the property of the contributing authors.
The copyright for certain compilations of material taken from this website is held by the SchematicsEditorsGroup - see ContributorAgreement & LGPL.
Other than such compilations, this material can be redistributed and/or modified under the terms of the GNU Lesser General Public License (LGPL), version 2.1, as published by the Free Software Foundation.
Ideas, requests, problems regarding Schematics Cookbook? Send feedback.
/ You are Main.guest