summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralainfrisch <alain@frisch.fr>2015-11-30 09:57:30 +0100
committeralainfrisch <alain@frisch.fr>2015-11-30 09:57:30 +0100
commit37ad7ece0eb6943b4a175bbceb7277605ea5ef8f (patch)
treedf8f192872b359226597082b26c9ce990d69a702
parenta1bb57048cebbfa1a173d8574371d38d3635e1fc (diff)
downloadocaml-37ad7ece0eb6943b4a175bbceb7277605ea5ef8f.tar.gz
GPR#210: keep unflushed out channels around to be able to flush them during at_exit.
-rw-r--r--byterun/io.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/byterun/io.c b/byterun/io.c
index 17995267be..eff504d0e2 100644
--- a/byterun/io.c
+++ b/byterun/io.c
@@ -439,9 +439,29 @@ CAMLexport void caml_finalize_channel(value vchan)
chan->name
);
- unlink_channel(chan);
- caml_stat_free(chan->name);
- caml_stat_free(chan);
+ if (chan->max == NULL && chan->curr != chan->buff){
+ /*
+ This is an unclosed out channel (chan->max == NULL) with a
+ non-empty buffer: keep it around so the OCaml [at_exit] function
+ gets a chance to flush it. We would want to simply flush the
+ channel now, but (i) flushing can raise exceptions, and (ii) it
+ is potentially a blocking operation. Both are forbidden in a
+ finalization function.
+
+ Refs:
+ http://caml.inria.fr/mantis/view.php?id=6902
+ https://github.com/ocaml/ocaml/pull/210
+ */
+ if (chan->name && caml_runtime_warnings_active())
+ fprintf(stderr,
+ "[ocaml] (moreover, it has unflushed data)\n",
+ chan->name
+ );
+ } else {
+ unlink_channel(chan);
+ caml_stat_free(chan->name);
+ caml_stat_free(chan);
+ }
}
static int compare_channel(value vchan1, value vchan2)