io_engine/
callback_worker.rs

1use crate::tasks::{IOCallback, IOEvent};
2use crossfire::{MTx, Tx, flavor::Flavor, mpmc};
3
4/// A trait for workers that accept IO events.
5///
6/// This allows using either `IOWorkers` (wrappers around channels) or direct channels
7/// (`MTx`, `Tx`) or any other sink, or even process inline.
8pub trait Worker<C: IOCallback>: Send + 'static {
9    fn done(&self, event: IOEvent<C>);
10}
11
12/// Implement with crossfire::mpmc, can be shared among multiple IOContext instances.
13pub struct IOWorkers<C: IOCallback>(pub(crate) MTx<mpmc::Array<IOEvent<C>>>);
14
15impl<C: IOCallback> IOWorkers<C> {
16    pub fn new(workers: usize) -> Self {
17        let (tx, rx) = mpmc::bounded_blocking::<IOEvent<C>>(100000);
18        for _i in 0..workers {
19            let _rx = rx.clone();
20            std::thread::spawn(move || {
21                loop {
22                    match _rx.recv() {
23                        Ok(event) => event.callback_merged(),
24                        Err(_) => {
25                            debug!("IOWorkers exit");
26                            return;
27                        }
28                    }
29                }
30            });
31        }
32        Self(tx)
33    }
34}
35
36impl<C: IOCallback> Clone for IOWorkers<C> {
37    fn clone(&self) -> Self {
38        Self(self.0.clone())
39    }
40}
41
42impl<C: IOCallback> Worker<C> for IOWorkers<C> {
43    fn done(&self, item: IOEvent<C>) {
44        let _ = self.0.send(item);
45    }
46}
47
48// Implement Worker for Crossfire MTx (Multi-Producer)
49impl<C, F> Worker<C> for MTx<F>
50where
51    F: Flavor<Item = IOEvent<C>> + crossfire::flavor::FlavorMP,
52    C: IOCallback,
53{
54    fn done(&self, item: IOEvent<C>) {
55        let _ = self.send(item);
56    }
57}
58
59// Implement Worker for Crossfire Tx (Single-Producer)
60impl<C, F> Worker<C> for Tx<F>
61where
62    F: Flavor<Item = IOEvent<C>>,
63    C: IOCallback,
64{
65    fn done(&self, item: IOEvent<C>) {
66        let _ = self.send(item);
67    }
68}
69
70/// Inline worker that executes callbacks directly without spawning threads.
71/// Use this for very lightweight callback logic to avoid thread context switching overhead.
72pub struct Inline;
73
74impl<C: IOCallback> Worker<C> for Inline {
75    fn done(&self, event: IOEvent<C>) {
76        event.callback_merged();
77    }
78}