caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Bigarrays and temporar C pointers
@ 2005-01-15 23:40 Daniel Bünzli
  2005-01-16  2:28 ` [Caml-list] " John Prevost
  0 siblings, 1 reply; 3+ messages in thread
From: Daniel Bünzli @ 2005-01-15 23:40 UTC (permalink / raw)
  To: caml-list caml-list

Hello,

Suppose that I have a C library which allows me to access data via a 
temporar pointer with the following interface  :

> void *map(void);  /* Returns a valid pointer to data */
> int map_size(void);  /* Returns the size of the data in bytes. */
> void unmap(void);  /* Invalidates the last pointer returned by map. */

Mapping data to a pointer must only be done for a short period of time: 
map, get size, process data, and unmap.

I would like to be able to process data in ocaml with bigarrays. To do 
so I provide the ocaml function `map'. This function maps the pointer, 
pass it as a bigarray to a user callback to process the data and then 
unmaps the pointer.

> open Bigarray;;
>
> type ('a, 'b) data = ('a, 'b, c_layout) Array1.t
>
> val map : ('a, b) kind -> (('a, 'b) data -> unit) -> unit

Map is implemented as follow (C primitives are at the end of the mail),

> external _map_ptr : ('a, 'b) kind -> ('a, 'b) data = "stub_map_ptr"
> external _unmap_ptr : ('a, 'b) data -> unit = "stub_unmap_ptr"
>
> let map k f =
>   let a = _map_ptr k in
>   f a;
>   _unmap_ptr a

My problem is that the provided bigarray may escape the scope of the 
user callback (e.g. by setting a global reference to the bigarray) 
potentially allowing the user to access data at an invalid pointer 
position after the pointer was invalidated.

In fact for the bigarray itself it is not a problem, I set its 
dimension to zero when I unmap it in _unmap_ptr (see the C 
implementation below) so access outside the user callback raise 
exceptions. However, according to my experiments and wandering in the 
implementation of bigarray this doesn't work if the user extracts a 
subarray with Array1.sub and sets it to a global variable.

Is there a solution to make that completely safe or I can only warn the 
user that he should not to try to escape data from the callback ?

Thanks for your help,

Daniel


The implementation of the C primitives :

> extern int bigarray_element_size[]; /* bigarray_stubs.c */
>
> CAMLprim value stub_map_ptr (value kind)
> {
>   void *p = map ();
>   long dim = map_size () / bigarray_element_size[Int_val (kind)];
>   int flag = Int_val (kind) | BIGARRAY_C_LAYOUT | BIGARRAY_EXTERNAL;
>   return alloc_bigarray(flag, 1, p, &dim);
> }
>
> CAMLprim value stub_unmap_ptr (value b)
> {
>   struct caml_bigarray *arr = Bigarray_val(b);
>   arr->data = NULL;
>   arr->dim[0] = 0;
>   unmap();
>   return Val_unit;
> }


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2005-01-16 12:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-01-15 23:40 Bigarrays and temporar C pointers Daniel Bünzli
2005-01-16  2:28 ` [Caml-list] " John Prevost
2005-01-16 12:31   ` Daniel Bünzli

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).