jpegxl_rs/parallel/
threads_runner.rs

1/*
2This file is part of jpegxl-rs.
3
4jpegxl-rs is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 3 of the License, or
7(at your option) any later version.
8
9jpegxl-rs is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with jpegxl-rs.  If not, see <https://www.gnu.org/licenses/>.
16*/
17
18//! Wrapper for default thread pool implementation with C++ standard library
19
20use std::{ffi::c_void, ptr::null_mut};
21
22#[allow(clippy::wildcard_imports)]
23use jpegxl_sys::threads::thread_parallel_runner::*;
24
25use super::{JxlParallelRunner, ParallelRunner};
26
27use crate::memory::MemoryManager;
28
29/// Wrapper for default thread pool implementation with C++ standard library
30pub struct ThreadsRunner<'mm> {
31    runner_ptr: *mut c_void,
32    _memory_manager: Option<&'mm dyn MemoryManager>,
33}
34
35impl<'mm> ThreadsRunner<'mm> {
36    /// Construct with number of threads
37    #[must_use]
38    pub fn new(
39        memory_manager: Option<&'mm dyn MemoryManager>,
40        num_workers: Option<usize>,
41    ) -> Option<Self> {
42        let mm = memory_manager.map(MemoryManager::manager);
43        let runner_ptr = unsafe {
44            JxlThreadParallelRunnerCreate(
45                mm.as_ref().map_or(null_mut(), |mm| mm),
46                num_workers.unwrap_or_else(|| JxlThreadParallelRunnerDefaultNumWorkerThreads()),
47            )
48        };
49
50        if runner_ptr.is_null() {
51            None
52        } else {
53            Some(Self {
54                runner_ptr,
55                _memory_manager: memory_manager,
56            })
57        }
58    }
59}
60
61impl Default for ThreadsRunner<'_> {
62    fn default() -> Self {
63        Self {
64            runner_ptr: unsafe {
65                JxlThreadParallelRunnerCreate(
66                    std::ptr::null(),
67                    JxlThreadParallelRunnerDefaultNumWorkerThreads(),
68                )
69            },
70            _memory_manager: None,
71        }
72    }
73}
74
75impl ParallelRunner for ThreadsRunner<'_> {
76    fn runner(&self) -> JxlParallelRunner {
77        JxlThreadParallelRunner
78    }
79
80    fn as_opaque_ptr(&self) -> *mut c_void {
81        self.runner_ptr
82    }
83}
84
85impl Drop for ThreadsRunner<'_> {
86    fn drop(&mut self) {
87        unsafe { JxlThreadParallelRunnerDestroy(self.runner_ptr) };
88    }
89}
90
91#[cfg(test)]
92mod tests {
93    use crate::memory::tests::BumpManager;
94
95    use super::*;
96
97    #[test]
98    fn test_construction() {
99        let memory_manager = BumpManager::new(1024);
100        let parallel_runner = ThreadsRunner::new(Some(&memory_manager), Some(10));
101        assert!(parallel_runner.is_some());
102    }
103}