@@ -14,21 +14,8 @@ use core::{
1414 sync:: atomic:: { AtomicPtr , Ordering } ,
1515} ;
1616
17- lazy_static ! {
18- static ref REGISTRY : Registry = Registry {
19- callsites: LinkedList :: new( ) ,
20- dispatchers: Mutex :: new( Vec :: new( ) ) ,
21- } ;
22- }
23-
24- type Dispatchers = Vec < dispatcher:: Registrar > ;
2517type Callsites = LinkedList ;
2618
27- struct Registry {
28- callsites : Callsites ,
29- dispatchers : Mutex < Dispatchers > ,
30- }
31-
3219/// Trait implemented by callsites.
3320///
3421/// These functions are only intended to be called by the callsite registry, which
@@ -76,98 +63,176 @@ pub struct Registration<T = &'static dyn Callsite> {
7663 next : AtomicPtr < Registration < T > > ,
7764}
7865
79- /// Clear and reregister interest on every [`Callsite`]
80- ///
81- /// This function is intended for runtime reconfiguration of filters on traces
82- /// when the filter recalculation is much less frequent than trace events are.
83- /// The alternative is to have the [`Subscriber`] that supports runtime
84- /// reconfiguration of filters always return [`Interest::sometimes()`] so that
85- /// [`enabled`] is evaluated for every event.
86- ///
87- /// This function will also re-compute the global maximum level as determined by
88- /// the [`max_level_hint`] method. If a [`Subscriber`]
89- /// implementation changes the value returned by its `max_level_hint`
90- /// implementation at runtime, then it **must** call this function after that
91- /// value changes, in order for the change to be reflected.
92- ///
93- /// [`max_level_hint`]: super::subscriber::Subscriber::max_level_hint
94- /// [`Callsite`]: super::callsite::Callsite
95- /// [`enabled`]: super::subscriber::Subscriber::enabled
96- /// [`Interest::sometimes()`]: super::subscriber::Interest::sometimes
97- /// [`Subscriber`]: super::subscriber::Subscriber
98- pub fn rebuild_interest_cache ( ) {
99- let mut dispatchers = REGISTRY . dispatchers . lock ( ) . unwrap ( ) ;
100- let callsites = & REGISTRY . callsites ;
101- rebuild_interest ( callsites, & mut dispatchers) ;
102- }
66+ #[ cfg( feature = "std" ) ]
67+ pub ( crate ) use self :: inner:: register_dispatch;
68+ pub use self :: inner:: { rebuild_interest_cache, register} ;
10369
104- /// Register a new `Callsite` with the global registry.
105- ///
106- /// This should be called once per callsite after the callsite has been
107- /// constructed.
108- pub fn register ( registration : & ' static Registration ) {
109- let mut dispatchers = REGISTRY . dispatchers . lock ( ) . unwrap ( ) ;
110- rebuild_callsite_interest ( & mut dispatchers, registration. callsite ) ;
111- REGISTRY . callsites . push ( registration) ;
112- }
70+ #[ cfg( feature = "std" ) ]
71+ mod inner {
72+ use super :: * ;
73+ use std:: vec:: Vec ;
74+ type Dispatchers = Vec < dispatcher:: Registrar > ;
11375
114- pub ( crate ) fn register_dispatch ( dispatch : & Dispatch ) {
115- let mut dispatchers = REGISTRY . dispatchers . lock ( ) . unwrap ( ) ;
116- let callsites = & REGISTRY . callsites ;
76+ struct Registry {
77+ callsites : Callsites ,
78+ dispatchers : Mutex < Dispatchers > ,
79+ }
11780
118- dispatchers. push ( dispatch. registrar ( ) ) ;
81+ lazy_static ! {
82+ static ref REGISTRY : Registry = Registry {
83+ callsites: LinkedList :: new( ) ,
84+ dispatchers: Mutex :: new( Vec :: new( ) ) ,
85+ } ;
86+ }
11987
120- rebuild_interest ( callsites, & mut dispatchers) ;
121- }
88+ /// Clear and reregister interest on every [`Callsite`]
89+ ///
90+ /// This function is intended for runtime reconfiguration of filters on traces
91+ /// when the filter recalculation is much less frequent than trace events are.
92+ /// The alternative is to have the [`Subscriber`] that supports runtime
93+ /// reconfiguration of filters always return [`Interest::sometimes()`] so that
94+ /// [`enabled`] is evaluated for every event.
95+ ///
96+ /// This function will also re-compute the global maximum level as determined by
97+ /// the [`max_level_hint`] method. If a [`Subscriber`]
98+ /// implementation changes the value returned by its `max_level_hint`
99+ /// implementation at runtime, then it **must** call this function after that
100+ /// value changes, in order for the change to be reflected.
101+ ///
102+ /// [`max_level_hint`]: super::subscriber::Subscriber::max_level_hint
103+ /// [`Callsite`]: super::callsite::Callsite
104+ /// [`enabled`]: super::subscriber::Subscriber::enabled
105+ /// [`Interest::sometimes()`]: super::subscriber::Interest::sometimes
106+ /// [`Subscriber`]: super::subscriber::Subscriber
107+ pub fn rebuild_interest_cache ( ) {
108+ let mut dispatchers = REGISTRY . dispatchers . lock ( ) . unwrap ( ) ;
109+ let callsites = & REGISTRY . callsites ;
110+ rebuild_interest ( callsites, & mut dispatchers) ;
111+ }
122112
123- fn rebuild_callsite_interest (
124- dispatchers : & mut MutexGuard < ' _ , Vec < dispatcher:: Registrar > > ,
125- callsite : & ' static dyn Callsite ,
126- ) {
127- let meta = callsite. metadata ( ) ;
128-
129- // Iterate over the subscribers in the registry, and — if they are
130- // active — register the callsite with them.
131- let mut interests = dispatchers. iter ( ) . filter_map ( |registrar| {
132- registrar
133- . upgrade ( )
134- . map ( |dispatch| dispatch. register_callsite ( meta) )
135- } ) ;
136-
137- // Use the first subscriber's `Interest` as the base value.
138- let interest = if let Some ( interest) = interests. next ( ) {
139- // Combine all remaining `Interest`s.
140- interests. fold ( interest, Interest :: and)
141- } else {
142- // If nobody was interested in this thing, just return `never`.
143- Interest :: never ( )
144- } ;
145-
146- callsite. set_interest ( interest)
147- }
113+ /// Register a new `Callsite` with the global registry.
114+ ///
115+ /// This should be called once per callsite after the callsite has been
116+ /// constructed.
117+ pub fn register ( registration : & ' static Registration ) {
118+ let mut dispatchers = REGISTRY . dispatchers . lock ( ) . unwrap ( ) ;
119+ rebuild_callsite_interest ( & mut dispatchers, registration. callsite ) ;
120+ REGISTRY . callsites . push ( registration) ;
121+ }
148122
149- fn rebuild_interest (
150- callsites : & Callsites ,
151- dispatchers : & mut MutexGuard < ' _ , Vec < dispatcher:: Registrar > > ,
152- ) {
153- let mut max_level = LevelFilter :: OFF ;
154- dispatchers. retain ( |registrar| {
155- if let Some ( dispatch) = registrar. upgrade ( ) {
156- // If the subscriber did not provide a max level hint, assume
157- // that it may enable every level.
158- let level_hint = dispatch. max_level_hint ( ) . unwrap_or ( LevelFilter :: TRACE ) ;
159- if level_hint > max_level {
160- max_level = level_hint;
161- }
162- true
123+ pub ( crate ) fn register_dispatch ( dispatch : & Dispatch ) {
124+ let mut dispatchers = REGISTRY . dispatchers . lock ( ) . unwrap ( ) ;
125+ let callsites = & REGISTRY . callsites ;
126+
127+ dispatchers. push ( dispatch. registrar ( ) ) ;
128+
129+ rebuild_interest ( callsites, & mut dispatchers) ;
130+ }
131+
132+ fn rebuild_callsite_interest (
133+ dispatchers : & mut MutexGuard < ' _ , Vec < dispatcher:: Registrar > > ,
134+ callsite : & ' static dyn Callsite ,
135+ ) {
136+ let meta = callsite. metadata ( ) ;
137+
138+ // Iterate over the subscribers in the registry, and — if they are
139+ // active — register the callsite with them.
140+ let mut interests = dispatchers. iter ( ) . filter_map ( |registrar| {
141+ registrar
142+ . upgrade ( )
143+ . map ( |dispatch| dispatch. register_callsite ( meta) )
144+ } ) ;
145+
146+ // Use the first subscriber's `Interest` as the base value.
147+ let interest = if let Some ( interest) = interests. next ( ) {
148+ // Combine all remaining `Interest`s.
149+ interests. fold ( interest, Interest :: and)
163150 } else {
164- false
165- }
166- } ) ;
151+ // If nobody was interested in this thing, just return `never`.
152+ Interest :: never ( )
153+ } ;
167154
168- callsites. for_each ( |reg| rebuild_callsite_interest ( dispatchers, reg. callsite ) ) ;
155+ callsite. set_interest ( interest)
156+ }
157+
158+ fn rebuild_interest (
159+ callsites : & Callsites ,
160+ dispatchers : & mut MutexGuard < ' _ , Vec < dispatcher:: Registrar > > ,
161+ ) {
162+ let mut max_level = LevelFilter :: OFF ;
163+ dispatchers. retain ( |registrar| {
164+ if let Some ( dispatch) = registrar. upgrade ( ) {
165+ // If the subscriber did not provide a max level hint, assume
166+ // that it may enable every level.
167+ let level_hint = dispatch. max_level_hint ( ) . unwrap_or ( LevelFilter :: TRACE ) ;
168+ if level_hint > max_level {
169+ max_level = level_hint;
170+ }
171+ true
172+ } else {
173+ false
174+ }
175+ } ) ;
169176
170- LevelFilter :: set_max ( max_level) ;
177+ callsites. for_each ( |reg| rebuild_callsite_interest ( dispatchers, reg. callsite ) ) ;
178+
179+ LevelFilter :: set_max ( max_level) ;
180+ }
181+ }
182+
183+ #[ cfg( not( feature = "std" ) ) ]
184+ mod inner {
185+ use super :: * ;
186+ static REGISTRY : Callsites = LinkedList :: new ( ) ;
187+
188+ /// Clear and reregister interest on every [`Callsite`]
189+ ///
190+ /// This function is intended for runtime reconfiguration of filters on traces
191+ /// when the filter recalculation is much less frequent than trace events are.
192+ /// The alternative is to have the [`Subscriber`] that supports runtime
193+ /// reconfiguration of filters always return [`Interest::sometimes()`] so that
194+ /// [`enabled`] is evaluated for every event.
195+ ///
196+ /// This function will also re-compute the global maximum level as determined by
197+ /// the [`max_level_hint`] method. If a [`Subscriber`]
198+ /// implementation changes the value returned by its `max_level_hint`
199+ /// implementation at runtime, then it **must** call this function after that
200+ /// value changes, in order for the change to be reflected.
201+ ///
202+ /// [`max_level_hint`]: super::subscriber::Subscriber::max_level_hint
203+ /// [`Callsite`]: super::callsite::Callsite
204+ /// [`enabled`]: super::subscriber::Subscriber::enabled
205+ /// [`Interest::sometimes()`]: super::subscriber::Interest::sometimes
206+ /// [`Subscriber`]: super::subscriber::Subscriber
207+ pub fn rebuild_interest_cache ( ) {
208+ rebuild_interest ( & REGISTRY , crate :: dispatcher:: get_global ( ) ) ;
209+ }
210+
211+ /// Register a new `Callsite` with the global registry.
212+ ///
213+ /// This should be called once per callsite after the callsite has been
214+ /// constructed.
215+ pub fn register ( registration : & ' static Registration ) {
216+ rebuild_callsite_interest ( crate :: dispatcher:: get_global ( ) , registration. callsite ) ;
217+ REGISTRY . push ( registration) ;
218+ }
219+
220+ fn rebuild_callsite_interest ( dispatcher : & ' static Dispatch , callsite : & ' static dyn Callsite ) {
221+ let meta = callsite. metadata ( ) ;
222+
223+ callsite. set_interest ( dispatcher. register_callsite ( meta) )
224+ }
225+
226+ fn rebuild_interest ( callsites : & Callsites , dispatcher : & dyn Subscriber ) {
227+ let mut max_level = LevelFilter :: OFF ;
228+ // If the subscriber did not provide a max level hint, assume
229+ // that it may enable every level.
230+ let level_hint = dispatcher. max_level_hint ( ) . unwrap_or ( LevelFilter :: TRACE ) ;
231+
232+ callsites. for_each ( |reg| rebuild_callsite_interest ( dispatcher, reg. callsite ) ) ;
233+
234+ LevelFilter :: set_max ( max_level) ;
235+ }
171236}
172237
173238// ===== impl Identifier =====
@@ -222,17 +287,19 @@ impl fmt::Debug for Registration {
222287// ===== impl LinkedList =====
223288
224289/// An intrusive atomic push-only linked list.
225- struct LinkedList {
226- head : AtomicPtr < Registration > ,
290+ struct LinkedList < T = & ' static dyn Callsite > {
291+ head : AtomicPtr < Registration < T > > ,
227292}
228293
229- impl LinkedList {
230- fn new ( ) -> Self {
294+ impl < T > LinkedList < T > {
295+ const fn new ( ) -> Self {
231296 LinkedList {
232297 head : AtomicPtr :: new ( ptr:: null_mut ( ) ) ,
233298 }
234299 }
300+ }
235301
302+ impl LinkedList {
236303 fn for_each ( & self , mut f : impl FnMut ( & ' static Registration ) ) {
237304 let mut head = self . head . load ( Ordering :: Acquire ) ;
238305
0 commit comments