Skip to main content

rustalign_concurrency/
work_queue.rs

1//! Thread-safe work queue for parallel processing
2//!
3//! This matches the C++ threadsafe_queue class and provides
4//! a lock-free queue alternative using crossbeam.
5
6use std::collections::VecDeque;
7use std::sync::{Arc, Mutex};
8
9/// Thread-safe work queue
10///
11/// This matches the C++ threadsafe_queue class that wraps
12/// std::queue with a mutex for thread-safe access.
13pub struct WorkQueue<T> {
14    queue: Arc<Mutex<VecDeque<T>>>,
15}
16
17impl<T> WorkQueue<T> {
18    /// Create a new empty work queue
19    pub fn new() -> Self {
20        Self {
21            queue: Arc::new(Mutex::new(VecDeque::new())),
22        }
23    }
24
25    /// Push a value onto the queue
26    pub fn push(&self, value: T) {
27        let mut queue = self.queue.lock().unwrap();
28        queue.push_back(value);
29    }
30
31    /// Try to pop a value from the queue
32    ///
33    /// Returns true if a value was popped, false if queue is empty
34    pub fn try_pop(&self) -> Option<T> {
35        let mut queue = self.queue.lock().unwrap();
36        queue.pop_front()
37    }
38
39    /// Get the current size of the queue
40    pub fn size(&self) -> usize {
41        let queue = self.queue.lock().unwrap();
42        queue.len()
43    }
44
45    /// Check if the queue is empty
46    pub fn is_empty(&self) -> bool {
47        self.size() == 0
48    }
49}
50
51impl<T> Clone for WorkQueue<T> {
52    fn clone(&self) -> Self {
53        Self {
54            queue: Arc::clone(&self.queue),
55        }
56    }
57}
58
59impl<T> Default for WorkQueue<T> {
60    fn default() -> Self {
61        Self::new()
62    }
63}
64
65#[cfg(test)]
66mod tests {
67    use super::*;
68
69    #[test]
70    fn test_work_queue() {
71        let queue = WorkQueue::new();
72        assert!(queue.is_empty());
73
74        queue.push(1);
75        queue.push(2);
76        assert_eq!(queue.size(), 2);
77
78        assert_eq!(queue.try_pop(), Some(1));
79        assert_eq!(queue.try_pop(), Some(2));
80        assert_eq!(queue.try_pop(), None);
81        assert!(queue.is_empty());
82    }
83
84    #[test]
85    fn test_work_queue_clone() {
86        let queue1 = WorkQueue::new();
87        queue1.push(42);
88
89        let queue2 = queue1.clone();
90        assert_eq!(queue2.try_pop(), Some(42));
91        assert_eq!(queue1.try_pop(), None);
92    }
93}