Propagates any panic captured while the scope was executing.
(&self)
| 377 | /// remainder are dropped. |
| 378 | /// |
| 379 | /// This function never unwinds, but may abort in circumstances. |
| 380 | #[cold] |
| 381 | fn store_panic(&self, err: Box<dyn Any + Send + 'static>) { |
| 382 | // Create an abort guard that will prevent this function from unwinding. |
| 383 | let abort_guard = AbortOnDrop; |
| 384 | // Check if the panic pointer has already been set. This lets us avoid |
| 385 | // allocating a second time, and means we can immediately drop the panic |
| 386 | // we have just been passed. |
| 387 | if self.panic.load(Ordering::Relaxed).is_null() { |
| 388 | let nil = ptr::null_mut(); |
| 389 | let err_ptr = Box::into_raw(Box::new(err)); |
| 390 | // Try to atomically swap the panic pointer from null to the newly |
| 391 | // allocated error slot. If this succeeds, the write occurs with |
| 392 | // `Release` ordering, which establishes a happens-before |
| 393 | // relationship with the fence in `maybe_propagate_panic`, so that |
| 394 | // the heap-allocated error will be visible to the reader. |
| 395 | // |
| 396 | // If the write fails, another panic must have already occurred, and |
| 397 | // we don't need to synchronize memory (the previous call to |
| 398 | // `store_panic` handles the synchronization for it's panic data). |
| 399 | if self |
| 400 | .panic |
| 401 | .compare_exchange( |
no test coverage detected