herculesabqp 0.1.2

A convex box-constrained quadratic programming solver with warm starts and active-set polishing.
Documentation
use std::sync::{Arc, OnceLock, RwLock};

type LogSink = Arc<dyn Fn(&str) + Send + Sync>;

fn sink_cell() -> &'static RwLock<Option<LogSink>> {
    static CELL: OnceLock<RwLock<Option<LogSink>>> = OnceLock::new();
    CELL.get_or_init(|| RwLock::new(None))
}

#[doc(hidden)]
pub fn install_log_sink(sink: Option<Arc<dyn Fn(&str) + Send + Sync>>) {
    let mut guard = sink_cell()
        .write()
        .expect("runtime log sink lock should not be poisoned");
    *guard = sink;
}

pub(crate) fn emit_log_line(line: &str) {
    let sink = sink_cell()
        .read()
        .expect("runtime log sink lock should not be poisoned")
        .clone();
    if let Some(sink) = sink {
        sink(line);
    } else {
        println!("{line}");
    }
}