[ocaml-ctypes] Finalising data

Florian Pichlmeier florian.pichlmeier at mytum.de
Mon May 19 15:20:25 BST 2014


Dear Jeremy,

thanks a lot for your comprehensive response.

I will change my api to include explicit destroy 
functions for messages.

But now i have encountered a new problem.
Zeromq uses incomplete types for many data types,
like the frame type
typedef struct _zframe_t zframe_t;

On the OCaml side i use void pointer to represent 
these data types, and thats where the problem arose.

The frame destroy function call for example is that
    zframe_destroy (zframe_t **self_p);
with the corresponding ocaml function

let destroy (msg : t) = 
let stub = foreign "zframe_destroy" (ptr void @-> returning int) in
stub (msg +@ 0)

The problem is the msg +@ 0 part.

Do you know a way around this problem?

Thanks again for your efforts,

Florian
 
Jeremy Yallop <yallop at gmail.com> wrote:


> Dear Florian,
> 
> On 30/04/2014, Florian Pichlmeier <florian.pichlmeier at mytum.de> wrote:
> 
> > i have this create function
> > 
> > type t = unit ptr
> > let zframe : t typ = ptr void
> > let zframe_opt : t option typ = ptr_opt void
> > 
> > let create msg =
> >   let stub = foreign "zframe_new"
> >       (string @-> size_t @-> returning zframe_opt)
> >   in
> >   let msg_size =  Size_t.of_int (String.length msg) in
> >   match stub msg msg_size with
> >   | None -> raise Frame_creation
> >   | Some x -> x
> > 
> > How can i tell the garbage collector to call my specific
> > destroy function?
> > 
> > 
> 
> You can attach a finaliser, either to the zframe value itself, or to
> another object which has the same lifetime as the zframe.  The
> drawback of attaching the finaliser directly to the zframe is that a
> number of ctypes functions (e.g. the functions for pointer arithmetic)
> create new ptr values, so you may end up destroying the object while
> you still have a pointer to it.  For example:
> 
>     let zf = create msg in
>     let () = Gc.finalise destroy_zframe zf in
>       (zf +@ 0)
>     (* At this point you still have a pointer to the zframe you
>        created, but the original Ctypes.ptr value has gone, so the
>        GC is free to run the finaliser attached to it. *)
> 
> If you're already wrapping the zframe in a larger OCaml value, such as
> a record, it would probably be wiser to attach the finaliser to that
> value instead, since you can see more easily in your own code exactly
> when copies are made.  If you want even stronger guarantees, you
> should make sure that the type you use to wrap the zframe has a
> mutable field, since the runtime is free to make copies of immutable
> values.
> 
> It may be more advisable to consider an alternative interface that
> makes the lifetime of your zframes deterministic and explicit.  One
> simple approach is to follow the design of the channel interfaces in
> the standard library, and expose a pair of functions
> 
>    val create : string -> t
>    val destroy : t -> unit
> 
> then leave it up to the user to ensure that destroy_zframe is closed
> at an appropriate moment (but perhaps catching other errors, such as
> double closes).
> 
> An alternative approach is to follow the design often used in Scheme,
> and expose a single higher-order function that manages the lifetime of
> the frame.  For example, if you have a function with the following
> interface
> 
>    val with_zframe : string -> (t -> 'a) -> 'a
> 
> then you might call it as follows
> 
>    with_zframe msg
>      (fun zframe ->
>          (* body: the zframe value is "live" here *)
>      )
> 
> and the user can be confident that -- whether the body finishes
> normally or with an exception -- with_zframe will destroy the value in
> a timely way.  This approach is used in the Batteries library to
> manage files: see with_file_in and with_file_out, for example:
> 
>    http://ocaml-batteries-team.github.io/batteries-included/hdoc2/BatFile.html#VALwith_file_in
>    http://ocaml-batteries-team.github.io/batteries-included/hdoc2/BatFile.html#VALwith_file_out
> 
> I hope that helps,
> 
> Jeremy.
> 
> 
> 


More information about the Ctypes mailing list