/rust/registry/src/index.crates.io-1949cf8c6b5b557f/flexi_logger-0.27.4/src/threads.rs
Line | Count | Source |
1 | | use { |
2 | | crate::{primary_writer::PrimaryWriter, writers::LogWriter, FlexiLoggerError}, |
3 | | std::{ |
4 | | collections::HashMap, |
5 | | sync::{ |
6 | | mpsc::{channel, Receiver, Sender}, |
7 | | Arc, |
8 | | }, |
9 | | thread::Builder as ThreadBuilder, |
10 | | }, |
11 | | }; |
12 | | |
13 | | #[cfg(feature = "async")] |
14 | | use { |
15 | | crate::{ |
16 | | primary_writer::std_stream::StdStream, |
17 | | util::{eprint_err, ErrorCode, ASYNC_FLUSH, ASYNC_SHUTDOWN}, |
18 | | }, |
19 | | crossbeam_channel::Receiver as CrossbeamReceiver, |
20 | | crossbeam_queue::ArrayQueue, |
21 | | std::{sync::Mutex, thread::JoinHandle}, |
22 | | }; |
23 | | |
24 | | // no clue why we get a warning if this allow is omitted; if we omit the use, we get an error |
25 | | #[allow(unused_imports)] |
26 | | #[cfg(feature = "async")] |
27 | | use std::io::Write; |
28 | | |
29 | | #[cfg(feature = "async")] |
30 | | const ASYNC_STD_WRITER: &str = "flexi_logger-async_std_writer"; |
31 | | const FLUSHER: &str = "flexi_logger-flusher"; |
32 | | |
33 | | // Used in Logger |
34 | 0 | pub(crate) fn start_flusher_thread( |
35 | 0 | primary_writer: Arc<PrimaryWriter>, |
36 | 0 | other_writers: Arc<HashMap<String, Box<dyn LogWriter>>>, |
37 | 0 | flush_interval: std::time::Duration, |
38 | 0 | ) -> Result<(), FlexiLoggerError> { |
39 | 0 | let builder = ThreadBuilder::new().name(FLUSHER.to_string()); |
40 | | #[cfg(not(feature = "dont_minimize_extra_stacks"))] |
41 | 0 | let builder = builder.stack_size(128); |
42 | | |
43 | 0 | builder.spawn(move || { |
44 | 0 | let (_sender, receiver): (Sender<()>, Receiver<()>) = channel(); |
45 | | loop { |
46 | 0 | receiver.recv_timeout(flush_interval).ok(); |
47 | 0 | primary_writer.flush().ok(); |
48 | 0 | for w in other_writers.values() { |
49 | 0 | w.flush().ok(); |
50 | 0 | } |
51 | | } |
52 | 0 | })?; |
53 | 0 | Ok(()) |
54 | 0 | } |
55 | | |
56 | | #[cfg(feature = "async")] |
57 | | pub(crate) fn start_async_stdwriter( |
58 | | mut std_stream: StdStream, |
59 | | receiver: CrossbeamReceiver<std::vec::Vec<u8>>, |
60 | | t_pool: Arc<ArrayQueue<Vec<u8>>>, |
61 | | msg_capa: usize, |
62 | | #[cfg(test)] t_validation_buffer: Arc<Mutex<std::io::Cursor<Vec<u8>>>>, |
63 | | ) -> Mutex<Option<JoinHandle<()>>> { |
64 | | Mutex::new(Some( |
65 | | ThreadBuilder::new() |
66 | | .name( |
67 | | ASYNC_STD_WRITER.to_string() |
68 | | ) |
69 | | .spawn(move || { |
70 | | loop { |
71 | | match receiver.recv() { |
72 | | Err(_) => break, |
73 | | Ok(mut message) => { |
74 | | match message.as_ref() { |
75 | | ASYNC_FLUSH => { |
76 | | std_stream |
77 | | .deref_mut() |
78 | | .flush() |
79 | | .unwrap_or_else( |
80 | | |e| eprint_err(ErrorCode::Flush, "flushing failed", &e) |
81 | | ); |
82 | | } |
83 | | ASYNC_SHUTDOWN => { |
84 | | break; |
85 | | } |
86 | | _ => { |
87 | | std_stream |
88 | | .deref_mut() |
89 | | .write_all(&message) |
90 | | .unwrap_or_else( |
91 | | |e| eprint_err(ErrorCode::Write,"writing failed", &e) |
92 | | ); |
93 | | #[cfg(test)] |
94 | | if let Ok(mut guard) = t_validation_buffer.lock() { |
95 | | (*guard).write_all(&message).ok(); |
96 | | } |
97 | | } |
98 | | } |
99 | | if message.capacity() <= msg_capa { |
100 | | message.clear(); |
101 | | t_pool.push(message).ok(); |
102 | | } |
103 | | } |
104 | | } |
105 | | } |
106 | | }) |
107 | | .unwrap(/* yes, let's panic if the thread can't be spawned */), |
108 | | )) |
109 | | } |