From 6708a866ced09f662b5217f202e8ae2896aadd1a Mon Sep 17 00:00:00 2001 From: Gabriel Scherer Date: Tue, 18 Apr 2023 20:51:17 +0200 Subject: Merge pull request #11876 from gadmm/echec_remove_global_roots_in_finalizer Document the situation regarding `remove_global_root` inside custom finalizers (cherry picked from commit cd195d6f4f8696af36efaea82941482e92f85464) --- Changes | 13 +++++++++++++ manual/src/cmds/intf-c.etex | 33 ++++++++++++++++++--------------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/Changes b/Changes index 4b59dac0e7..4f9d6ff260 100644 --- a/Changes +++ b/Changes @@ -29,6 +29,19 @@ OCaml 5.1.0 ### Runtime system: +* #11865, #11868, #11876: Clarify that the operations of a custom + block must never access the OCaml runtime. The previous + documentation only mentioned the main illicit usages. In particular, + since OCaml 5.0, it is no longer safe to call + `caml_remove_global_root` or `caml_remove_generational_global_root` + from within the C finalizer of a custom block, or within the + finalization function passed to `caml_alloc_final`. As a workaround, + such a finalization operation can be registered with `Gc.finalize` + instead, which guarantees to run the finalizer at a safe point. + (Report by Timothy Bourke, discussion by Yotam Barnoy, Timothy + Bourke, Sadiq Jaffer, Xavier Leroy, Guillaume Munch-Maccagnoni, and + Gabriel Scherer) + - #12130: Fix multicore crashes with weak hash sets. Fixes #11934. (Nick Barnes, review by François Bobot) diff --git a/manual/src/cmds/intf-c.etex b/manual/src/cmds/intf-c.etex index 1b2311fde3..cd3c283b1a 100644 --- a/manual/src/cmds/intf-c.etex +++ b/manual/src/cmds/intf-c.etex @@ -1993,11 +1993,12 @@ the serialized output. \end{itemize} Note: the "finalize", "compare", "hash", "serialize" and "deserialize" -functions attached to custom block descriptors must never trigger a -garbage collection. Within these functions, do not call any of the -OCaml allocation functions, and do not perform a callback into OCaml -code. Do not use "CAMLparam" to register the parameters to these -functions, and do not use "CAMLreturn" to return the result. +functions attached to custom block descriptors must never access the +OCaml runtime. Within these functions, do not call any of the OCaml +allocation functions, and do not perform a callback into OCaml code. +Do not use "CAMLparam" to register the parameters to these functions, +and do not use "CAMLreturn" to return the result. Do not raise +exceptions, do not remove global roots, etc. \subsection{ss:c-custom-alloc}{Allocating custom blocks} @@ -2149,17 +2150,19 @@ as identifiers, to minimize the risk of identifier collision. \subsection{ss:c-finalized}{Finalized blocks} Custom blocks generalize the finalized blocks that were present in -OCaml prior to version 3.00. For backward compatibility, the -format of custom blocks is compatible with that of finalized blocks, -and the "alloc_final" function is still available to allocate a custom +OCaml prior to version 3.00. For backwards compatibility, the format +of custom blocks is compatible with that of finalized blocks, and the +"caml_alloc_final" function is still available to allocate a custom block with a given finalization function, but default comparison, -hashing and serialization functions. "caml_alloc_final("\var{n}", -"\var{f}", "\var{used}", "\var{max}")" returns a fresh custom block of -size \var{n}+1 words, with finalization function \var{f}. The first -word is reserved for storing the custom operations; the other -\var{n} words are available for your data. The two parameters -\var{used} and \var{max} are used to control the speed of garbage -collection, as described for "caml_alloc_custom". +hashing and serialization functions. (In particular, the finalization +function must not access the OCaml runtime.) + +"caml_alloc_final("\var{n}", "\var{f}", "\var{used}", "\var{max}")" +returns a fresh custom block of size \var{n}+1 words, with +finalization function \var{f}. The first word is reserved for storing +the custom operations; the other \var{n} words are available for your +data. The two parameters \var{used} and \var{max} are used to control +the speed of garbage collection, as described for "caml_alloc_custom". \section{s:C-Bigarrays}{Advanced topic: Bigarrays and the OCaml-C interface} -- cgit v1.2.1