@@ -1140,24 +1140,24 @@ mod tests {
11401140 ) ;
11411141 }
11421142
1143- #[ tokio:: test( flavor = "multi_thread" , worker_threads = 1 ) ]
1144- async fn test_simple_processor_async_exporter_with_runtime ( ) {
1145- let exporter = LogExporterThatRequiresTokio :: new ( ) ;
1146- let processor = SimpleLogProcessor :: new ( Box :: new ( exporter. clone ( ) ) ) ;
1147-
1148- let mut record: LogRecord = Default :: default ( ) ;
1149- let instrumentation: InstrumentationLibrary = Default :: default ( ) ;
1150-
1151- processor. emit ( & mut record, & instrumentation) ;
1152-
1153- assert_eq ! ( exporter. len( ) , 1 ) ;
1154- }
1155-
11561143 #[ tokio:: test( flavor = "multi_thread" , worker_threads = 4 ) ]
11571144 #[ ignore]
1158- // All worker threads except one are blocked, waiting for the export operation to complete.
1159- // The exporter, which isn't blocked, requires the runtime to proceed, but no free worker threads are available, resulting in a deadlock.
1160- // This mimics the scenario where the
1145+ // This test demonstrates a potential deadlock scenario in a multi-threaded Tokio runtime.
1146+ // It spawns Tokio tasks equal to the number of runtime worker threads (4) to emit log events.
1147+ // Each task attempts to acquire a mutex on the SimpleLogProcessor. Only one task obtains the lock,
1148+ // while the others are blocked, waiting for its release.
1149+ //
1150+ // The task holding the lock invokes the LogExporterThatRequiresTokio, which performs an
1151+ // asynchronous operation (e.g., network I/O simulated by `tokio::sleep`). This operation
1152+ // requires yielding control back to the Tokio runtime to make progress.
1153+ //
1154+ // However, all worker threads are occupied:
1155+ // - One thread is executing the async exporter operation
1156+ // - Three threads are blocked waiting for the mutex
1157+ //
1158+ // This leads to a deadlock as there are no available threads to drive the async operation
1159+ // to completion, preventing the mutex from being released. Consequently, neither the blocked
1160+ // tasks nor the exporter can proceed.
11611161 async fn test_simple_processor_async_exporter_with_all_runtime_worker_threads_blocked ( ) {
11621162 let exporter = LogExporterThatRequiresTokio :: new ( ) ;
11631163 let processor = Arc :: new ( Mutex :: new ( SimpleLogProcessor :: new ( Box :: new (
@@ -1181,13 +1181,37 @@ mod tests {
11811181 handles. push ( handle) ;
11821182 }
11831183
1184+ // below code won't get executed
11841185 for handle in handles {
11851186 handle. await . unwrap ( ) ;
11861187 }
1187- assert_eq ! ( exporter. len( ) , 4 ) ;
1188+ assert_eq ! ( exporter. len( ) , concurrent_emit) ;
1189+ }
1190+
1191+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 1 ) ]
1192+ // This test uses a multi-threaded runtime setup with a single worker thread. Note that even
1193+ // though only one worker thread is created, it is distinct from the main thread. The processor
1194+ // emits a log event, and the exporter performs an async operation that requires the runtime.
1195+ // The single worker thread handles this operation without deadlocking, as long as no other
1196+ // tasks occupy the runtime.
1197+ async fn test_simple_processor_async_exporter_with_runtime ( ) {
1198+ let exporter = LogExporterThatRequiresTokio :: new ( ) ;
1199+ let processor = SimpleLogProcessor :: new ( Box :: new ( exporter. clone ( ) ) ) ;
1200+
1201+ let mut record: LogRecord = Default :: default ( ) ;
1202+ let instrumentation: InstrumentationLibrary = Default :: default ( ) ;
1203+
1204+ processor. emit ( & mut record, & instrumentation) ;
1205+
1206+ assert_eq ! ( exporter. len( ) , 1 ) ;
11881207 }
11891208
11901209 #[ tokio:: test( flavor = "multi_thread" ) ]
1210+ // This test uses a multi-threaded runtime setup with the default number of worker threads.
1211+ // The processor emits a log event, and the exporter, which requires the runtime for its async
1212+ // operations, can access one of the available worker threads to complete its task. As there
1213+ // are multiple threads, the exporter can proceed without blocking other tasks, ensuring the
1214+ // test completes successfully.
11911215 async fn test_simple_processor_async_exporter_with_multi_thread_runtime ( ) {
11921216 let exporter = LogExporterThatRequiresTokio :: new ( ) ;
11931217
@@ -1202,9 +1226,12 @@ mod tests {
12021226 }
12031227
12041228 #[ tokio:: test( flavor = "current_thread" ) ]
1205- #[ ignore] // the current thread is blocked with futures::block_on to
1206- // complete the export, and the exporter further needs tokio runtime to progress
1207- // on this blocked thread, resulting in deadlock.
1229+ #[ ignore]
1230+ // This test uses a current-thread runtime, where all operations run on the main thread.
1231+ // The processor emits a log event while the runtime is blocked using `futures::block_on`
1232+ // to complete the export operation. The exporter, which performs an async operation and
1233+ // requires the runtime, cannot progress because the main thread is already blocked.
1234+ // This results in a deadlock, as the runtime cannot move forward.
12081235 async fn test_simple_processor_async_exporter_with_current_thread_runtime ( ) {
12091236 let exporter = LogExporterThatRequiresTokio :: new ( ) ;
12101237
0 commit comments