ocaml-opentelemetry/src/client/util_thread.ml

64 lines
1.6 KiB
OCaml

open Common_
(** start a thread in the background, running [f()], blocking signals *)
let start_bg_thread (f : unit -> unit) : Thread.t =
let unix_run () =
let signals =
[
Sys.sigusr1;
Sys.sigusr2;
Sys.sigterm;
Sys.sigpipe;
Sys.sigalrm;
Sys.sigstop;
]
in
ignore (Thread.sigmask Unix.SIG_BLOCK signals : _ list);
f ()
in
(* no signals on Windows *)
let run () =
if Sys.win32 then
f ()
else
unix_run ()
in
Thread.create run ()
(** thread that calls [tick()] regularly, to help enforce timeouts *)
let setup_ticker_thread ~stop ~sleep_ms (exp : OTEL.Exporter.t) () =
let sleep_s = float sleep_ms /. 1000. in
let tick_loop () =
try
while not @@ Atomic.get stop do
Thread.delay sleep_s;
OTEL.Exporter.tick exp
done
with
| Sync_queue.Closed -> ()
| exn ->
(* print and ignore *)
Printf.eprintf "otel-ocurl: ticker thread: uncaught exn:\n%s\n%!"
(Printexc.to_string exn)
in
start_bg_thread tick_loop
module MCond = struct
type t = {
mutex: Mutex.t;
cond: Condition.t;
}
let create () : t = { mutex = Mutex.create (); cond = Condition.create () }
let signal self = Condition.signal self.cond
let[@inline] protect self f = Util_mutex.protect self.mutex f
(** NOTE: the mutex must be acquired *)
let wait self = Condition.wait self.cond self.mutex
(** Ensure we get signalled when the queue goes from empty to non-empty *)
let wakeup_from_bq (self : t) (bq : _ Bounded_queue.t) : unit =
Bounded_queue.on_non_empty bq (fun () -> signal self)
end