rust_htslib/tpool.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
use std::cell::RefCell;
use std::sync::Arc;
pub use crate::errors::{Error, Result};
use crate::htslib;
/// An HTSlib thread pool. Create a thread pool and use `set_thread_pool()` methods
/// to share a thread pool across multiple BAM readers & writers.
/// The Rust wrapper holds the htslib thread pool behind a Rc, and a Rc reference
/// to the thread pool is held by each reader / writer so you don't need to
/// explicitly manage the lifetime of the `ThreadPool`.
#[derive(Clone, Debug)]
pub struct ThreadPool {
pub(crate) handle: Arc<RefCell<InnerThreadPool>>,
}
impl ThreadPool {
/// Create a new thread pool with `n_threads` threads.
pub fn new(n_threads: u32) -> Result<ThreadPool> {
let ret = unsafe { htslib::hts_tpool_init(n_threads as i32) };
if ret.is_null() {
Err(Error::ThreadPool)
} else {
let inner = htslib::htsThreadPool {
pool: ret,
// this matches the default size
// used in hts_set_threads.
qsize: n_threads as i32 * 2,
};
let inner = InnerThreadPool { inner };
let handle = Arc::new(RefCell::new(inner));
Ok(ThreadPool { handle })
}
}
}
/// Internal htsThreadPool
#[derive(Clone, Debug)]
pub struct InnerThreadPool {
pub(crate) inner: htslib::htsThreadPool,
}
impl Drop for InnerThreadPool {
fn drop(&mut self) {
if !self.inner.pool.is_null() {
unsafe {
htslib::hts_tpool_destroy(self.inner.pool);
}
}
self.inner.pool = std::ptr::null_mut();
}
}