@@ -26,7 +26,7 @@ use crate::{
2626use opentelemetry:: { otel_warn, InstrumentationScope } ;
2727
2828use std:: fmt:: Debug ;
29- use std:: sync:: atomic :: { AtomicBool , Ordering } ;
29+ use std:: sync:: Mutex ;
3030
3131/// A [`LogProcessor`] designed for testing and debugging purpose, that immediately
3232/// exports log records as they are emitted. Log records are exported synchronously
@@ -60,15 +60,15 @@ use std::sync::atomic::{AtomicBool, Ordering};
6060#[ derive( Debug ) ]
6161pub struct SimpleLogProcessor < T : LogExporter > {
6262 exporter : T ,
63- is_exporting : AtomicBool ,
63+ export_mutex : Mutex < ( ) > ,
6464}
6565
6666impl < T : LogExporter > SimpleLogProcessor < T > {
6767 /// Creates a new instance of `SimpleLogProcessor`.
6868 pub fn new ( exporter : T ) -> Self {
6969 SimpleLogProcessor {
7070 exporter,
71- is_exporting : AtomicBool :: new ( false ) ,
71+ export_mutex : Mutex :: new ( ( ) ) ,
7272 }
7373 }
7474}
@@ -78,23 +78,13 @@ impl<T: LogExporter> LogProcessor for SimpleLogProcessor<T> {
7878 // export() does not require mutable self and can be called in parallel
7979 // with other export() calls. However, OTel Spec requires that
8080 // existing export() must be completed before the next export() call.
81- while !self
82- . is_exporting
83- . compare_exchange ( false , true , Ordering :: Acquire , Ordering :: Relaxed )
84- . is_ok ( )
85- {
86- // Another thread is currently exporting, yield to let other work proceed
87- std:: thread:: yield_now ( ) ;
88- }
81+ let _guard = self . export_mutex . lock ( ) . unwrap ( ) ;
8982
9083 // We now have exclusive access to export
9184 let result = {
9285 let log_tuple = & [ ( record as & SdkLogRecord , instrumentation) ] ;
9386 futures_executor:: block_on ( self . exporter . export ( LogBatch :: new ( log_tuple) ) )
9487 } ;
95-
96- // Release the lock
97- self . is_exporting . store ( false , Ordering :: Release ) ;
9888 if let Err ( err) = result {
9989 otel_warn ! (
10090 name: "SimpleLogProcessor.Emit.ExportError" ,
0 commit comments