@@ -163,6 +163,7 @@ type t =
163163 ; mutable bytes_written : int (* Total written bytes. Wraps. *)
164164 ; mutable state : state
165165 ; mutable wake_writer : unit -> unit
166+ ; mutable printf : (Format .formatter * bool ref ) option
166167 }
167168(* Invariant: [write_pos >= scheduled_pos] *)
168169
@@ -377,6 +378,7 @@ let of_buffer ?sw buffer =
377378 ; bytes_written = 0
378379 ; state = Active
379380 ; wake_writer = ignore
381+ ; printf = None
380382 }
381383 in
382384 begin match sw with
@@ -422,19 +424,26 @@ let make_formatter t =
422424 (fun () -> flush t)
423425
424426let printf t =
425- let is_formatting = ref true in
426- let ppf =
427- Format. make_formatter
428- (fun buf off len -> write_gen t buf ~off ~len ~blit: Bigstringaf. blit_from_string)
429- (fun () ->
430- (* As per the Format module manual, an explicit flush writes to the
431- output channel and ensures that "all pending text is displayed"
432- and "these explicit flush calls [...] could dramatically impact efficiency".
433- Therefore it is clear that we need to call `flush t` instead of `flush_buffer t`. *)
434- if ! is_formatting then flush t)
427+ let ppf, is_formatting =
428+ match t.printf with
429+ | Some x -> x
430+ | None ->
431+ let is_formatting = ref true in
432+ let ppf =
433+ Format. make_formatter
434+ (fun buf off len -> write_gen t buf ~off ~len ~blit: Bigstringaf. blit_from_string)
435+ (fun () ->
436+ (* As per the Format module manual, an explicit flush writes to the
437+ output channel and ensures that "all pending text is displayed"
438+ and "these explicit flush calls [...] could dramatically impact efficiency".
439+ Therefore it is clear that we need to call `flush t` instead of `flush_buffer t`. *)
440+ if ! is_formatting then flush t)
441+ in
442+ t.printf < - Some (ppf, is_formatting);
443+ ppf, is_formatting
435444 in
436445 Format. kfprintf (fun ppf ->
437- assert ! is_formatting;
446+ if not ! is_formatting then raise ( Sys_error " Buf_write.printf: invalid concurrent access " ) ;
438447 (* Ensure that [ppf]'s internal buffer is flushed to [t], but without flushing [t] itself: *)
439448 is_formatting := false ;
440449 Format. pp_print_flush ppf ()
0 commit comments