@@ -27,6 +27,8 @@
#include <caml/custom.h>
#include <caml/fail.h>
#include <caml/callback.h>
+#include <caml/unixsupport.h>
+#include <caml/signals.h>
#define Intf_val(a) ((struct mmap_interface *) Data_abstract_val(a))
@@ -35,7 +37,9 @@ static int mmap_interface_init(struct mmap_interface *intf,
int len, int offset)
{
intf->len = len;
+ caml_enter_blocking_section();
intf->addr = mmap(NULL, len, pflag, mflag, fd, offset);
+ caml_leave_blocking_section();
return (intf->addr == MAP_FAILED) ? errno : 0;
}
@@ -64,17 +68,22 @@ CAMLprim value stub_mmap_init(value fd, value pflag, value mflag,
if (mmap_interface_init(Intf_val(result), Int_val(fd),
c_pflag, c_mflag,
Int_val(len), Int_val(offset)))
- caml_failwith("mmap");
+ uerror("mmap", Nothing);
CAMLreturn(result);
}
CAMLprim value stub_mmap_final(value intf)
{
CAMLparam1(intf);
+ struct mmap_interface interface = *Intf_val(intf);
- if (Intf_val(intf)->addr != MAP_FAILED)
- munmap(Intf_val(intf)->addr, Intf_val(intf)->len);
+ /* mark it as freed, in case munmap below fails, so we don't retry it */
Intf_val(intf)->addr = MAP_FAILED;
+ if (interface.addr != MAP_FAILED) {
+ caml_enter_blocking_section();
+ munmap(interface.addr, interface.len);
+ caml_leave_blocking_section();
+ }
CAMLreturn(Val_unit);
}
These functions can potentially take some time, so allow other OCaml code to proceed meanwhile (if any). Also raise a Unix_error based on `errno` if `mmap` fails, instead of just calling failwith (which would lose the error reason). Signed-off-by: Edwin Török <edvin.torok@citrix.com> --- Changes since v2: * repost of lost patch from 2020 (posted to ML on 2021 https://patchwork.kernel.org/project/xen-devel/patch/294a60be29027d33b0a1d154b7d576237c7dd420.1620755942.git.edvin.torok@citrix.com/) --- tools/ocaml/libs/mmap/xenmmap_stubs.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)