On this page:
allocator
deallocator
releaser
retainer

5.6 Allocation and Finalization

The ffi/unsafe/alloc library provides utilities for ensuring that values allocated through foreign functions are reliably deallocated.

procedure

((allocator dealloc) alloc)  (or/c procedure? #f)

  dealloc : (any/c . -> . any)
  alloc : (or/c procedure? #f)
Produces an allocator procedure that behaves like alloc, but each result v of the allocator, if not #f, is given a finalizer that calls dealloc on vunless the call has been canceled by applying a deallocator (produced by deallocator) to v. Any existing dealloc registered for v is canceled. If and only if alloc is #f, ((allocator alloc) dealloc) produces #f.

The resulting allocator calls alloc in atomic mode (see call-as-atomic). The result from alloc is received and registered in atomic mode, so that the result is reliably deallocated as long as no exception is raised.

The dealloc procedure will be called in atomic mode, and it must obey the same constraints as a finalizer procedure provided to register-finalizer. The dealloc procedure itself need not be specifically a deallocator produced by deallocator. If a deallocator is called explicitly, it need not be the same as dealloc.

When a non-main place exits, after all custodian-shutdown actions, for every dealloc still registered via an allocator or retainer (from allocator or retainer), the value to deallocate is treated as immediately unreachable. At that point, dealloc functions are called in reverse order of their registrations. Note that references in a dealloc function’s closure do not prevent running a dealloc function for any other value. If deallocation needs to proceed in an order different than reverse of allocation, use a retainer to insert a new deallocation action that will run earlier.

Changed in version 7.0.0.4 of package base: Added atomic mode for dealloc and changed non-main place exits to call all remaining deallocs.
Changed in version 7.4.0.4: Produce #f when alloc is #f.

procedure

((deallocator [get-arg]) dealloc)  procedure?

  get-arg : (list? . -> . any/c) = car
  dealloc : procedure?

procedure

((releaser [get-arg]) dealloc)  procedure?

  get-arg : (list? . -> . any/c) = car
  dealloc : procedure?
Produces a deallocator procedure that behaves like dealloc. The deallocator calls dealloc in atomic mode (see call-as-atomic), and for one of its arguments, the it cancels the most recent remaining deallocator registered by a allocator or retainer.

The optional get-arg procedure determines which of dealloc’s arguments correspond to the released object; get-arg receives a list of arguments passed to dealloc, so the default car selects the first one. Note that get-arg can only choose one of the by-position arguments to dealloc, though the deallocator will require and accept the same keyword arguments as dealloc, if any.

The releaser procedure is a synonym for deallocator.

procedure

((retainer release [get-arg]) retain)  procedure?

  release : (any/c . -> . any)
  get-arg : (list? . -> . any/c) = car
  retain : procedure?
Produces a retainer procedure that behaves like retain. A retainer acts the same as an allocator produced by allocator, except that

The optional get-arg procedure determines which of the retainer’s arguments (that is, which of retain’s arguments) correspond to the retained object v; get-arg receives a list of arguments passed to retain, so the default car selects the first one. Note that get-arg can only choose one of the by-position arguments to retain, though the retainer will require and accept the same keyword arguments as retain, if any.

Changed in version 7.0.0.4 of package base: Added atomic mode for release and changed non-main place exits to call all remaining releases.