From fb49472f3461d806c097e17487c31325478740dc Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Tue, 25 Nov 2025 19:43:50 -0500 Subject: [PATCH] fix: protect Eio's out channel with a mutex close #58 --- CHANGES.md | 5 +++++ src/eio/linol_eio.ml | 18 +++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 82fbcdfd..c24db338 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,4 +1,9 @@ +# 0.11 + +- breaking: the Eio library now needs the output channel to be paired with + an `Eio.Mutex.t` to prevent race conditions (#58) + # 0.10 - use `git subtree` to vendor lsp+jsonrpc, so that they diff --git a/src/eio/linol_eio.ml b/src/eio/linol_eio.ml index cadf4723..f676e201 100644 --- a/src/eio/linol_eio.ml +++ b/src/eio/linol_eio.ml @@ -9,7 +9,7 @@ module IO_eio : with type 'a t = 'a and type env = Eio_unix.Stdenv.base and type in_channel = Eio.Buf_read.t - and type out_channel = Eio_unix.sink_ty Eio.Std.r = struct + and type out_channel = Eio.Mutex.t * Eio_unix.sink_ty Eio.Std.r = struct type 'a t = 'a let ( let+ ) x f = f x @@ -28,17 +28,21 @@ module IO_eio : let stdin env = Eio.Buf_read.of_flow ~max_size:1_000_000 (Eio.Stdenv.stdin env) - let stdout = Eio.Stdenv.stdout + let stdout_mutex = Eio.Mutex.create () + let stdout env = stdout_mutex, Eio.Stdenv.stdout env type env = Eio_unix.Stdenv.base type in_channel = Eio.Buf_read.t - type out_channel = Eio_unix.sink_ty Eio.Std.r + type out_channel = Eio.Mutex.t * Eio_unix.sink_ty Eio.Std.r - let write_string out_ch str = Eio.Flow.copy_string str out_ch + let write_string (mutex, out_ch) str = + Eio.Mutex.use_rw ~protect:false mutex (fun () -> + Eio.Flow.copy_string str out_ch) - let write out_ch bytes off len = - Eio.Buf_write.with_flow out_ch @@ fun w -> - Eio.Buf_write.bytes w ~off ~len bytes + let write (mutex, out_ch) bytes off len = + Eio.Mutex.use_rw ~protect:false mutex (fun () -> + Eio.Buf_write.with_flow out_ch @@ fun w -> + Eio.Buf_write.bytes w ~off ~len bytes) let read in_ch bytes off len = let str = Eio.Buf_read.take len in_ch in