Harden concurrency and resource lifecycle (#101)
Some checks failed
Native code generation / deterministic (push) Failing after 2m4s
Concurrency and resource soak audit / soak (push) Failing after 6m31s
Imaging and meshing gate / native (push) Failing after 2m52s
JPEG 2000 feature / linux (push) Successful in 2m45s
Release platform and feature matrix / audit (push) Successful in 35s
Native Rust workspace compile / compile (push) Failing after 54s
Release platform and feature matrix / matrix (false, linux-stable-minimal, x86_64-unknown-linux-gnu, stable) (push) Has been cancelled
Release platform and feature matrix / matrix (false, macos-stable-portable, x86_64-apple-darwin, stable) (push) Has been cancelled
Release platform and feature matrix / matrix (false, windows-stable-portable, x86_64-pc-windows-gnu, stable) (push) Has been cancelled
Release platform and feature matrix / matrix (true, linux-msrv-portable, x86_64-unknown-linux-gnu, 1.96.0) (push) Has been cancelled
Release platform and feature matrix / matrix (true, linux-stable-default, x86_64-unknown-linux-gnu, stable) (push) Has been cancelled
Release platform and feature matrix / matrix (true, linux-stable-features, x86_64-unknown-linux-gnu, stable) (push) Has been cancelled
Release platform and feature matrix / matrix (true, linux-stable-release-surface, x86_64-unknown-linux-gnu, stable) (push) Has been cancelled
Dependency and supply-chain audit / audit (push) Has been cancelled
Skia feature / linux (push) Has been cancelled
Some checks failed
Native code generation / deterministic (push) Failing after 2m4s
Concurrency and resource soak audit / soak (push) Failing after 6m31s
Imaging and meshing gate / native (push) Failing after 2m52s
JPEG 2000 feature / linux (push) Successful in 2m45s
Release platform and feature matrix / audit (push) Successful in 35s
Native Rust workspace compile / compile (push) Failing after 54s
Release platform and feature matrix / matrix (false, linux-stable-minimal, x86_64-unknown-linux-gnu, stable) (push) Has been cancelled
Release platform and feature matrix / matrix (false, macos-stable-portable, x86_64-apple-darwin, stable) (push) Has been cancelled
Release platform and feature matrix / matrix (false, windows-stable-portable, x86_64-pc-windows-gnu, stable) (push) Has been cancelled
Release platform and feature matrix / matrix (true, linux-msrv-portable, x86_64-unknown-linux-gnu, 1.96.0) (push) Has been cancelled
Release platform and feature matrix / matrix (true, linux-stable-default, x86_64-unknown-linux-gnu, stable) (push) Has been cancelled
Release platform and feature matrix / matrix (true, linux-stable-features, x86_64-unknown-linux-gnu, stable) (push) Has been cancelled
Release platform and feature matrix / matrix (true, linux-stable-release-surface, x86_64-unknown-linux-gnu, stable) (push) Has been cancelled
Dependency and supply-chain audit / audit (push) Has been cancelled
Skia feature / linux (push) Has been cancelled
This commit is contained in:
@@ -28,6 +28,7 @@ use libremetaverse_types::{
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::panic::{AssertUnwindSafe, catch_unwind};
|
||||
use std::sync::atomic::{AtomicBool, AtomicI32, AtomicU64, Ordering};
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
|
||||
@@ -84,7 +85,8 @@ impl<T: 'static> EventRegistry<T> {
|
||||
fn emit_with(&self, mut event: impl FnMut() -> T) {
|
||||
let handlers: Vec<_> = mutex(&self.handlers).values().cloned().collect();
|
||||
for handler in handlers {
|
||||
handler(event());
|
||||
let argument = event();
|
||||
let _ = catch_unwind(AssertUnwindSafe(|| handler(argument)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2291,6 +2293,32 @@ fn inventory_item(value: &dyn InventoryObjectClass) -> Option<InventoryItem> {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn event_registry_isolates_panics_and_releases_subscriptions() {
|
||||
let registry = EventRegistry::<usize>::default();
|
||||
let released = Arc::new(());
|
||||
let released_probe = Arc::downgrade(&released);
|
||||
let panicking = registry.subscribe(Arc::new(|_| panic!("subscriber failure")));
|
||||
let delivered = Arc::new(AtomicU64::new(0));
|
||||
let delivered_handler = Arc::clone(&delivered);
|
||||
let releasing = Arc::clone(&released);
|
||||
let healthy = registry.subscribe(Arc::new(move |value| {
|
||||
let _keep_alive = &releasing;
|
||||
delivered_handler.fetch_add(value as u64, Ordering::AcqRel);
|
||||
}));
|
||||
drop(released);
|
||||
|
||||
registry.emit_with(|| 1);
|
||||
assert_eq!(delivered.load(Ordering::Acquire), 1);
|
||||
assert!(released_probe.upgrade().is_some());
|
||||
|
||||
drop(panicking);
|
||||
drop(healthy);
|
||||
assert!(released_probe.upgrade().is_none());
|
||||
registry.emit_with(|| 1);
|
||||
assert_eq!(delivered.load(Ordering::Acquire), 1);
|
||||
}
|
||||
|
||||
fn wearable(id: u64, wearable_type: WearableType, asset_type: AssetType) -> InventoryItem {
|
||||
let mut wearable = InventoryWearable::new(UUID::new_with_u_int64(id).unwrap()).unwrap();
|
||||
wearable.base.set_asset_type(asset_type);
|
||||
|
||||
Reference in New Issue
Block a user